Подтвердить что ты не робот

UserDetails getPassword возвращает null в spring безопасности 3.1. Как получить пароль от текущего пользователя?

Я реализовал функцию изменения пароля с помощью spring безопасности, но ((UserDetails)).getPassword()) возвращает значение null для зарегистрированного пользователя.

Если я правильно помню, это раньше работало в версии 3.0. Было ли это изменено в 3.1, чтобы не удалось получить текущий пароль зарегистрированного пользователя?

В приведенном ниже коде я проверяю текущий пароль, введенный пользователем, с веб-страницы. Затем я проверяю, соответствует ли зарегистрированный пароль пользователя введенному паролю. Если это так, я хочу установить oldPasswordMatchNewPassword = true.

Как реализовать эту функциональность?

@RequestMapping(value = "/account/changePassword.do", method = RequestMethod.POST)
    public String submitChangePasswordPage(
            @RequestParam("oldpassword") String oldPassword,
            @RequestParam("password") String newPassword) {
        Object principal = SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        String username = principal.toString();
        if (principal instanceof UserDetails) {
            username = ((UserDetails) principal).getUsername();
            System.out.println("username: " + username);
            System.out.println("password: "
                    + ((UserDetails) principal).getPassword());
            if (((UserDetails) principal).getPassword() != null) {
                if (((UserDetails) principal).getPassword().equals(oldPassword)) {
                    oldPasswordMatchNewPassword = true;
                }
            }
        }
    if (oldPasswordMatchNewPassword == true) {
        logger.info("Old password matches new password. Password will be updated.");
        changePasswordDao.changePassword(username, newPassword);
        SecurityContextHolder.clearContext();
        return "redirect:home.do";
    } else {
        logger.info("Old password did not match new password. Password will be not be updated.");
        return null;
    }
}

Я помещаю пару sysout() s, чтобы увидеть возвращаемые значения. Для ((UserDetails) принципала).getUsername() Я могу видеть правильно зарегистрированного пользователя. ((UserDetails)).getPassword() возвращает null.

Как мне получить ((UserDetails) принципал).getPassword() это значение?

Спасибо заранее!

4b9b3361

Ответ 1

Я использовал этот блок кода (erase-credentials = "false" ), чтобы исправить это. Я не знаю, является ли это изящным решением, но оно исправило мою проблему:

<authentication-manager alias="authenticationManager" erase-credentials="false">
    <!-- authentication-provider user-service-ref="userService" -->
    <authentication-provider>
        <jdbc-user-service data-source-ref="dataSource" />
    </authentication-provider>
</authentication-manager>

Ответ 2

Да, это изменилось в версии 3.1. Учетные данные удаляются после успешной аутентификации по умолчанию. Вы можете установить eraseCredentialsAfterAuthentication на false в ProviderManager, чтобы предотвратить это. См. Подробности здесь: http://static.springsource.org/spring-security/site/docs/3.2.x/reference/core-services.html#core-services-erasing-credentials

Ответ 3

Так как пароль не сохраняется в памяти после аутентификации пользователя (как правило, это хорошо), вам нужно будет явно перезагрузить его, чтобы использовать его. Альтернативная и более гибкая стратегия заключается в том, чтобы ввести экземпляр AuthenticationManager и использовать его напрямую:

String name = SecurityContextHolder.getContext().getAuthentication();

try {
    authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(name, oldPassword));
    // Update password here with your dao
} catch (AuthenticationException e) {
    // Old password was wrong
}

таким образом вам не нужно беспокоиться о таких вещах, как стратегии кодирования пароля. Обратите внимание, что вы не должны хранить пароли в виде обычного текста. Они должны быть хэшированы с помощью bcrypt или чего-то подобного.