Spring Security - 获取身份验证的明确密码并重新加密

时间:2017-11-08 15:15:18

标签: java spring encryption spring-security

我有一个包含MD5(遗留内容)和BCrypt密码的用户表。我想将MD5密码迁移到BCrypt,而不是强制它们。我想在成功验证时重新加密密码。

然而(到目前为止,在我的调查中),如果我在erase-credentials声明中禁用authentication-manager,我只能获得清除密码(来自登录页面)。在这种情况下,我不仅可以从我的自定义AuthenticationSuccessHandler访问凭据信息,还可以访问我的应用程序中的任何位置(使用SecurityContextHolder.getContext().getAuthentication())。

是否有办法在成功验证时访问清除密码?或者您是否知道更好的方法来重新加密密码而不要求用户操作(密码更改等)?

谢谢

1 个答案:

答案 0 :(得分:0)

解决方案是创建一个密码编码器,它接受来自新的更好(BCrypt)编码器的旧MD5哈希值和值,并在找到时迁移MD5哈希值。

@Component
public class MigratingPasswordEncoder implements PasswordEncoder {

    @Autowired
    private org.springframework.security.crypto.password.PasswordEncoder passwordEncoder; // new encoder (BCrypt)

    @Autowired
    private Md5PasswordEncoder legacyEncoder;

    @Autowired
    private UserDao userDao; // where password hashes are stored

    public String encodePassword(String rawPass, Object salt) {
        return passwordEncoder.encode(rawPass);
    }

    public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
        if (legacyEncoder.isPasswordValid(encPass, rawPass, salt)) {
            // MD5 hash found here, save a new hash instead
            userDao.updatePassword(encPass, passwordEncoder.encode(rawPass));
            return true;
        }
        return passwordEncoder.matches(rawPass, encPass);
    }
}

弃用说明:这使用PasswordEncoder包中的旧org.springframework.security.authentication.encoding接口,但由于Md5PasswordEncoder也使用该接口,所以这是不可避免的。

信用:灵感来自Spring security 3.1.4 and ShaPasswordEncoder deprecation的答案。