Spring security Spring security 3.1.4和ShaPasswordEncoder弃用

Spring security Spring security 3.1.4和ShaPasswordEncoder弃用,spring-security,Spring Security,今天,我将正在开发的应用程序的spring安全版本从3.1.3升级到了3.1.4,我注意到org.springframework.security.authentication.encoding.ShaPasswordEncoder类上有一个弃用警告 因此,我切换到新的org.springframework.security.crypto.password.StandardPasswordEncoder实现 我让它工作,我可以注册一个新用户并在我的应用程序中登录,但是,正如我担心的那样,我无法使

今天,我将正在开发的应用程序的spring安全版本从3.1.3升级到了3.1.4,我注意到
org.springframework.security.authentication.encoding.ShaPasswordEncoder
类上有一个弃用警告

因此,我切换到新的
org.springframework.security.crypto.password.StandardPasswordEncoder
实现

我让它工作,我可以注册一个新用户并在我的应用程序中登录,但是,正如我担心的那样,我无法使用以前的ShaPasswordEncoder和我的自定义salt生成的密码登录

由于我有一个已经注册了许多用户的数据库,我应该如何切换实现而不使旧的编码密码无效? 有可能吗


另请参见:

这是一个很好的问题,我期待着阅读一些答案


好吧,一次大规模更新是不可能做到的:你只是无法从散列中检索原始字符串。您必须在登录尝试期间检查提交的密码是否与其中一种策略匹配,并在必要时将其转换为新策略,但这意味着您必须使用这两种编码策略,直到所有用户都登录并因此转换了所有密码。对于新加入的开发人员来说,这不是很方便,也不一定直观。

如果您想切换到更安全的密码编码机制,那么我建议您使用。我将使用类似的方法迁移您的用户:

//实现旧的PasswordEncoder接口
公共类MigrateUsersPasswordEncoder实现PasswordEncoder{
@自动连线
ShaPasswordEncoder-legacyEncoder;
@自动连线
jdbc模板;
BCryptPasswordEncoder bcryptEncoder=新的BCryptPasswordEncoder();
@凌驾
公共字符串编码密码(字符串rawPass、对象salt){
返回bcryptEncoder.encode(rawPass);
}
@凌驾
公共布尔值isPasswordValid(字符串encPass、字符串rawPass、对象salt){
if(legacyEncoder.isPasswordValid(encPass、rawPass、salt)){
update(“更新用户设置密码=?其中密码=?”,bcryptEncoder.encode(rawPass),encPass);
返回true;
}
返回bcryptEncoder.matches(rawPass、encPass);
}
}
您可以通过密码字段的格式检查已迁移的用户比例。BCrypt字符串有一个独特的语法,以
$
符号开头


另一个答案指出,此代码可能会意外地同时更新多个密码。该问题说明使用了定制的盐,因此,如果随机选择盐,碰撞的机会可以忽略不计,但情况可能并非总是如此。如果更新了两个密码,会出现什么问题?然后可以从bcrypt哈希中检测到帐户具有相同的密码。无论如何都是这样,因为它要求SHA哈希值与更新相同。如果您认为这可能是一个问题(例如,由于盐选择不当,甚至使用了不含盐的散列),那么修改SQL以检测此问题并使用单独的BCrypt散列值执行多个更新将是微不足道的。

我试图在接受的答案中添加注释,但遗憾的是,我还没有足够的可信度:(

我相信接受答案的代码片段在更新数据库中的密码时有潜在的危险(这就是为什么假设可以找到旧密码的原因,我验证了这一点,至少在ShaPasswordEncoder上有一个空salt),您仍然无法保证密码在所有用户中是唯一的。您可能会碰巧与系统上的其他用户共享相同的密码,并且SQL代码最终会更改所有碰巧拥有您密码的用户

我认为最安全的策略是不更新用户的密码,而是提供迁移策略,计划最终删除ShaPasswordEncoder

  • 使用提供的示例代码
  • 删除更新数据库的代码
  • 添加“忘记密码”或“生成新密码”等功能,以处理删除ShaPasswordEncoder时用户未创建新密码的最终情况。例如,升级到已删除该密码的Spring Security时,或者选择自己删除该密码
  • 更新您的文档或明确说明在软件的下一个主要发行版本中,用户将不得不重新保存密码或必须使用前面提到的密码重置功能
  • 给用户一个主要版本发布周期的宽限期来过渡(他们可能不会这样做,只是被重置密码抓住了)

感谢您的代码。这或多或少是Spiff建议的。我的目标是能够升级到Spring Security的未来版本,而不需要同时有两个实现,而且只有在每个用户都登录的情况下,此解决方案才会起作用。我希望引入一个与旧ShaPasswor兼容的实现如果用户从未登录,则可能值得决定是否值得维护这些帐户(经过适当的审查期)。如果它们处于非活动状态,您可以暂时禁用它们,并向用户发送邮件,要求他们重置密码。不鼓励使用旧密码编码器,因为它们相对不安全,容易出错,并且与其他系统不兼容。这些类被弃用,以阻止在新应用中使用它们,但没有什么可以阻止您使用它们如果你真的不想使用更安全的选项,就唱出来。这是一个很好的观点。然而,我不认为与现有情况相比,这真的很危险,或者说