我正在开发一个基于 Spring MVC 的遗留 Web 应用程序,该应用程序使用 - 按照当前标准 - 不适当的散列算法。现在我想逐步将所有哈希迁移到 bcrypt。我的高级策略是:
- 默认情况下使用 bcrypt 生成新的哈希
- 当用户成功登录并且仍然有旧哈希时,应用程序会用新的 bcrypt 哈希替换旧哈希。
使用 Spring Security 实施此策略的最惯用的方法是什么?我应该使用自定义过滤器还是我的 AccessDecisionManager 或...?
我正在开发一个基于 Spring MVC 的遗留 Web 应用程序,该应用程序使用 - 按照当前标准 - 不适当的散列算法。现在我想逐步将所有哈希迁移到 bcrypt。我的高级策略是:
使用 Spring Security 实施此策略的最惯用的方法是什么?我应该使用自定义过滤器还是我的 AccessDecisionManager 或...?
您可能需要自定义您的AuthenticationProvider
的密码,因为那是密码与用户数据实际比较的地方,并且您拥有所需的所有信息。
在该authenticate
方法中,您将首先加载用户数据。BCryptPasswordEncoder
然后使用 a和您的旧密码检查用户提供的密码。如果两者都没有返回匹配项,则抛出一个BadCredentialsException
.
如果用户身份验证成功(非常重要:-))并且密码是旧格式(旧编码器匹配),那么您将调用一些额外的代码来更新用户的帐户数据并用 bcrypt 替换旧哈希。BCryptPasswordEncoder
也可用于创建新的哈希。
如果需要,您可以在进行比较之前提前检测存储的哈希是否已经 bcrypt。Bcrypt 字符串具有非常独特的格式。
另请注意,为了更难猜测有效的帐户名称,您应该尝试使该方法在提供的用户名存在和不存在时都表现相同(就所花费的时间而言)。因此,即使您没有提供的用户名的任何用户数据,也要调用编码器。
我认为最好的方法是为身份验证提供者指定密码编码器,如下所示,有关更多信息,请参阅doc
<authentication-manager>
<authentication-provider user-service-ref="userService">
<password-encoder ref="passwordEncoder">
<salt-source ref="saltSource" />
</password-encoder>
</authentication-provider>
</authentication-manager>
<beans:bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"
id="passwordEncoder" />
<beans:bean class="org.springframework.security.authentication.dao.ReflectionSaltSource"
id="saltSource">
<beans:property name="userPropertyToUse" value="userName" />
</beans:bean>