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