0

我尝试使用模拟登录,@WithMockUser但它不起作用。

@SpringBootTest
class RoleTest {
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    private User user;

    @BeforeEach
    void setUp() {
        AuthentificationService.AuthentificationMock.loginAsAdminOnly();
        user = new User("maier", "password", "Hansi", "Meier", "hanmai@maier.de", "+4953353535353", roleService.getByName(Role.ROLE_ADMIN).orElse(null));
        assertNotNull(user.getRoles());
        userService.save(user);
        AuthentificationService.AuthentificationMock.logout();
    }

    @AfterEach
    void tearDown() {
        AuthentificationService.AuthentificationMock.loginAsAdminOnly();
        userService.delete(user);
        AuthentificationService.AuthentificationMock.logout();
    }

    @Test
    @WithMockUser(Role.ADMIN)
    void testRoleHierarchy() {
        boolean succeeded = true;
        //WHEN

        try {
            final Optional<User> byUsername = userService.getByUsernameResolved(user.getUsername());
        } catch (Exception e) {
            succeeded = false;
        }
        //THEN
        assertTrue(succeeded, "ADMIN has no USER Privileges, check RoleHierarchy");
    }
}

如果我运行测试身份验证AuthenticationCredentialsNotFoundException,那么测试就会失败。

那就是访问受限的服务:

@Service
@Slf4j
@Transactional
@NoArgsConstructor
public class UserService implements JpaServiceContract<User>, UserDetailsService {
    private UserRepository userRepository;
    private AuthenticationManager authenticationManager;
    private PasswordEncoder passwordEncoder;

    @Autowired
    public UserService(PasswordEncoder passwordEncoder, AuthenticationManager authenticationManager, UserRepository userRepository) {
        this.userRepository = userRepository;
        this.authenticationManager = authenticationManager;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public UserDetails loadUserByUsername(@NotNull String username) {
        final String callerName = SharedSecrets.getJavaLangAccess().getStackTraceElement(new Throwable(), 12).getClassName();
        if (!callerName.equals("app.config.security.TokenAuthenticationFilter")) {
            throw new MethodAccessException();
        }
        SecurityContextHolder.getContext().setAuthentication(new PreAuthenticatedAuthenticationToken(null, null, Collections.singletonList(new Role(Role.ADMIN))));
        Optional<User> user = getByUsernameResolved(username);
        SecurityContextHolder.clearContext();
        final User user1 = user.orElse(null);
        assert user1 != null;
        return user1;
    }

    /**
     * This Method is same as {@link #getByUsername(String)} but it resolves all Lazy loaded Properties,
     * which could not be resolved outside of the current Transaction anymore
     *
     * @param username Of the {@link app.model.authentification.User} which should be found
     * @return The {@link app.model.authentification.User} found as an {@link java.util.Optional}
     */
    @RolesAllowed(value = Role.ROLE_USER)
    public Optional<User> getByUsernameResolved(@NotNull String username) {
        final Optional<User> userUnresolved = getByUsername(username);
        userUnresolved.ifPresent(user -> Hibernate.initialize(user.getRoles()));
        return userUnresolved;
    }

    @RolesAllowed(value = Role.ROLE_USER)
    public Optional<User> getByUsername(@NotNull String username) {

        if (!existsByUsername(username)) {
            throw new RessourceNotFoundException("User not found");
        }

        return userRepository.findByUsername(username);
    }

    @Override
    @RolesAllowed(Role.ROLE_USER)
    public Optional<User> getById(@NotNull Long id) {
        return userRepository.findById(id);
    }

    @Override
    @RolesAllowed(Role.ROLE_USER)
    public Optional<User> getByIdResolved(@NotNull Long id) {
        final Optional<User> byId = getById(id);
        if (byId.isPresent()) {
            Hibernate.initialize(byId.get().getRoles());
            return byId;
        } else {
            return Optional.empty();
        }
    }

    @RolesAllowed(value = Role.ROLE_ADMIN)
    @Override
    public Set<User> getAll() {
        return (Set<User>) userRepository.findAll();
    }

    @RolesAllowed(value = Role.ROLE_ADMIN)
    @Override
    public Set<User> getAllResolved() {
        final Set<User> all = getAll();
        Hibernate.initialize(all);
        return all;
    }

    public User changePassword(@NotNull String oldPassword, @NotNull String newPassword) {
        User user = getLoggedInUser();

        user.setPassword(passwordEncoder.encode(newPassword));
        return userRepository.save(user);

    }

    @Override
    @RolesAllowed(value = Role.ROLE_USER)
    public boolean existsById(@NotNull Long id) {
        return userRepository.existsById(id);
    }


    @RolesAllowed(value = Role.ROLE_USER)
    public boolean existsByUsername(@NotNull String username) {
        return userRepository.existsByUsername(username);
    }

    @Override
    @RolesAllowed(value = Role.ROLE_ADMIN)
    public User save(@NotNull User user) throws RessourceAlreadyExistsException, InvalidParameterException {
        if (UserValidator.isFullValid(user))
            if (!userRepository.existsByUsername(user.getUsername())) {
                user.setPassword(passwordEncoder.encode(user.getPassword()));
                return userRepository.save(user);
            } else {
                throw new RessourceAlreadyExistsException(user.getUsername());
            }
        throw new InvalidParameterException(new String[]{"User"});

    }

    @Override
    @RolesAllowed(Role.ROLE_USER)
    public User update(@NotNull User user) throws InvalidParameterException {
        if (UserValidator.isFullValid(user) && userRepository.existsByUsername(user.getUsername())) {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            return userRepository.save(user);
        }
        throw new InvalidParameterException(new String[]{"User"});
    }

    @Override
    @RolesAllowed(value = Role.ROLE_ADMIN)
    public void delete(@NotNull User user) throws IllegalArgumentException {
        userRepository.delete(user);
    }

    @RolesAllowed(value = Role.ROLE_ADMIN)
    public void delete(@NotNull String username) {
        userRepository.deleteByUsername(username);
    }

    @RolesAllowed(value = Role.ROLE_USER)
    private User getLoggedInUser() throws InvalidStateException {
        Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
        String username = currentUser.getName();
        final Optional<User> userValue = getByUsername(username);
        if (userValue.isPresent())
            return userValue.get();
        throw new InvalidStateException("User " + username + " not found");
    }


}

如果您愿意,我可以提供更多配置信息,但目前我不知道这是否有必要。但如果你相信它,我会的。

4

0 回答 0