Document Upgrading Password Encoding
Closes gh-17112 Signed-off-by: Mark Putsiata <m.putsiata@gmail.com>
This commit is contained in:
parent
e30dc42d1e
commit
465e13ae3d
|
@ -689,3 +689,54 @@ class CompromisedPasswordAuthenticationFailureHandler : AuthenticationFailureHan
|
|||
}
|
||||
----
|
||||
======
|
||||
|
||||
[[authentication-upgrading-password-encoding]]
|
||||
== Upgrading Password Encoding
|
||||
|
||||
Spring Security can automatically upgrade existing password encodings without asking users to reset their passwords. It uses the `PasswordEncoder.upgradeEncoding(String)` method to determine whether a stored password should be re-encoded for improved security.
|
||||
|
||||
If `PasswordEncoder.upgradeEncoding(String)` indicates an update is needed and a `UserDetailsPasswordService` bean is available, the framework will rehash the password immediately after a successful login. The raw password submitted at login is passed to `PasswordEncoder` to produce a stronger encoding. The `UserDetailsPasswordService` saves the newly encoded password in the user store (e.g., database or LDAP) and returns the updated `UserDetails`.
|
||||
|
||||
To enable this behavior, simply define a `UserDetailsPasswordService` bean. You can always provide your own `UserDetailsPasswordService` implementation tailored to your persistent user store.
|
||||
|
||||
For example, if you are using a `UserDetailsManager`, you can write:
|
||||
|
||||
.Using UserDetailsPasswordService with UserDetailsManager
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@Bean
|
||||
UserDetailsPasswordService userDetailsPasswordService(UserDetailsManager userDetailsManager) {
|
||||
return (user, newPassword) -> {
|
||||
UserDetails updated = User.withUserDetails(user)
|
||||
.password(newPassword)
|
||||
.build();
|
||||
userDetailsManager.updateUser(updated);
|
||||
return updated;
|
||||
};
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
@Bean
|
||||
open fun userDetailsPasswordService(userDetailsManager: UserDetailsManager): UserDetailsPasswordService {
|
||||
return UserDetailsPasswordService { user, newPassword ->
|
||||
val updated = User.withUserDetails(user)
|
||||
.password(newPassword)
|
||||
.build()
|
||||
userDetailsManager.updateUser(updated)
|
||||
updated
|
||||
}
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
When using xref:servlet/authentication/passwords/jdbc.adoc#servlet-authentication-jdbc-bean[JdbcUserDetailsManager], you do not need to register a separate `UserDetailsPasswordService` bean, since `JdbcUserDetailsManager` already implements that interface. You simply enable the upgrade mechanism by calling `JdbcUserDetailsManager.setEnableUpdatePassword(true)`.
|
||||
|
||||
This approach lets you migrate from weaker hashes to stronger algorithms (like <<authentication-password-storage-bcrypt,bcrypt>>) without impacting your users. Passwords are re-encoded only after successful authentication, enabling a gradual, transparent migration for your application.
|
||||
|
|
Loading…
Reference in New Issue