Spring Authestall Set Authentication объект не работает - PullRequest
2 голосов
/ 16 февраля 2012

У меня есть сценарий, в котором я должен заставить пользователей сбросить пароль при первом входе в систему.Для этого я использую пользовательский successAuthenticationHandler.Все, что пытается сделать этот обработчик - посмотреть, требует ли вошедший в систему пользователь сбросить пароль.Если да, создайте новый UsernamePasswordAuthenticationToken и установите его в SecurityContext.А затем перенаправить на resetPasswordUrl.

Вот мой метод onAuthenticationSuccess:

@Override
public void onAuthenticationSuccess(final HttpServletRequest request, final HttpServletResponse response,
        final Authentication authentication) throws ServletException, IOException {

    final AugmentedUser aUser = (AugmentedUser) SecurityContextHolder.getContext().getAuthentication()
            .getPrincipal();
    System.out.println("In password reset handler.");
    if (authorizationService.isPasswordResetRequired(aUser.getUsername(), aUser.getUsertype())) {
        LOG.debug("Password reset is required.");
        System.out.println("Password reset is required");
        final UsernamePasswordAuthenticationToken authRequest = reAssignUserWithOnlyResetPasswordRole(aUser,
                request);
        SecurityContextHolder.getContext().setAuthentication(authRequest);
        SecurityContextHolder.getContext().getAuthentication();
        System.out.println("User reassinged with only RESET_PASSWORD Authority, redirecting to resetPasswordPage");
        response.sendRedirect(resetPasswordUrl);

        //super.onAuthenticationSuccess(request, response, newAuthentication);
    } else {
        super.onAuthenticationSuccess(request, response, authentication);
    }

}

Если да, создайте еще один UsernamePasswordAuthenticationToken с теми же учетными данными, что и вошедший в систему пользователь, но просто назначьте ему одну роль «RESET_PASSWORD», так что он не может получить доступ к чему-либо еще, нажав любую другую ссылку / URL.

private UsernamePasswordAuthenticationToken reAssignUserWithOnlyResetPasswordRole(final AugmentedUser aUser,
        final HttpServletRequest request) {
    final String username = aUser.getUsername();
    final String password = aUser.getPassword();
    final boolean isEnabled = aUser.isEnabled();
    final boolean isAccountNonExpired = aUser.isAccountNonExpired();
    final boolean isCredentialsNonExpired = aUser.isCredentialsNonExpired();
    final boolean isAccountNonLocked = aUser.isAccountNonLocked();
    LOG.debug("Re-assigning the user: " + username + " with only RESET PASSWORD AUTHORITY");
    System.out.println("Re-assigning the user: " + username + "with only RESET PASSWORD AUTHORITY");
    final Map<String, String> userAttributesMap = new HashMap<String, String>();
    final AugmentedUser userWithResetPasswordRole = new AugmentedUser(username, password, aUser.getUsertype(),
            isEnabled, isAccountNonExpired, isCredentialsNonExpired, isAccountNonLocked,
            createResetPasswordGrantedAuhtority(), userAttributesMap);

    final UsernamePasswordAuthenticationToken authenticationRequest = new UsernamePasswordAuthenticationToken(
            userWithResetPasswordRole, userWithResetPasswordRole.getAuthorities());

    //WebAuthenticationDetails are required for sessionId and ipAddress
    final WebAuthenticationDetails webAuthenticationDetails = new WebAuthenticationDetails(request);
    authenticationRequest.setDetails(webAuthenticationDetails);

    return authenticationRequest;

}

Теперь я вижу, что новый UsernamePasswordAuthenticationToken создается только с ролью пароля RESET.Но похоже, что при перенаправлении на resetPasswordURl пружинный фильтр выполняет некоторые проверки, и после установки моего нового UsernamePasswordAuthenticationToken пользователь не проходит проверку подлинности.

Вот основная причина, которую я вижу в журналах:

doAuthentication - Authentication attempt using
org.springframework.security.authentication.dao.DaoAuthenticationProvider
2012-02-15 22:47:20,931 [http-8081-6] DEBUG       org.springframework.security.web.access.ExceptionTranslationFilter    org.springframework.security.web.access.ExceptionTranslationFilter handleException - Authentication exception occurred; redirecting to authentication entry point

org.springframework.security.authentication.BadCredentialsException: Bad credentials
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:67)
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:139)
at org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:120)

Любые комментарии, где я иду не так?

1 Ответ

1 голос
/ 21 февраля 2012

Трудно сказать без дополнительного контекста из журнала (остальная часть трассировки стека и предыдущие сообщения журнала), но я думаю, что вы используете неправильный конструктор для UsernamePasswordAuthenticationToken.По историческим причинам он принимает Object аргументов, которые не помогают.

Предполагается, что версия с двумя аргументами принимает имя пользователя и учетные данные и создает токен без аутентификации (для запроса), который недопустим изПерспектива перехватчика безопасности.Поэтому я предполагаю, что перехватчик пытается повторно аутентифицировать токен (это должно быть очевидно из стековой трассировки, откуда поступает вызов), и он терпит неудачу, потому что параметр credentials на самом деле представляет собой список прав доступа, а не пароль.1006 * Поэтому используйте:

new UsernamePasswordAuthenticationToken(
        userWithResetPasswordRole, null, userWithResetPasswordRole.getAuthorities());

.

Кроме того, вам потребуется пользовательский избиратель, который обрабатывает RESET_PASSWORD, поскольку он не будет распознаваться конфигурацией по умолчанию.В качестве альтернативы используйте префикс ROLE_, т.е. ROLE_RESET_PASSWORD.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...