我有一个包含MD5(遗留内容)和BCrypt密码的用户表。我想将MD5密码迁移到BCrypt,而不是强制它们。我想在成功验证时重新加密密码。
然而(到目前为止,在我的调查中),如果我在erase-credentials
声明中禁用authentication-manager
,我只能获得清除密码(来自登录页面)。在这种情况下,我不仅可以从我的自定义AuthenticationSuccessHandler
访问凭据信息,还可以访问我的应用程序中的任何位置(使用SecurityContextHolder.getContext().getAuthentication()
)。
是否有办法在成功验证时访问清除密码?或者您是否知道更好的方法来重新加密密码而不要求用户操作(密码更改等)?
谢谢
答案 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的答案。