Skip to content

Commit f3d704a

Browse files
committed
Add PasswordEncoder Preparation Steps
Issue gh-10506
1 parent 71eb71d commit f3d704a

File tree

1 file changed

+312
-0
lines changed

1 file changed

+312
-0
lines changed

docs/modules/ROOT/pages/migration.adoc

+312
Original file line numberDiff line numberDiff line change
@@ -3520,6 +3520,318 @@ open class SecurityConfiguration {
35203520
----
35213521
====
35223522

3523+
=== Update Password Encoding
3524+
3525+
In 6.0, password encoding minimums are updated for PBKDF2, SCrypt, and Argon2.
3526+
3527+
[NOTE]
3528+
====
3529+
If you are using the default password encoder, then there are no preparation steps to follow and this section can be skipped.
3530+
====
3531+
3532+
==== Update `Pbkdf2PasswordEncoder`
3533+
3534+
If you are xref:features/authentication/password-storage.adoc#authentication-password-storage-pbkdf2[using `Pbkdf2PasswordEncoder`], the constructors are replaced with static factories that refer to the Spring Security version that the given settings apply to.
3535+
3536+
===== Replace Deprecated Constructor Usage
3537+
3538+
If you use the default constructor, you should begin by changing:
3539+
3540+
====
3541+
.Java
3542+
[source,java,role="primary"]
3543+
----
3544+
@Bean
3545+
PasswordEncoder passwordEncoder() {
3546+
return new Pbkdf2PasswordEncoder();
3547+
}
3548+
----
3549+
3550+
.Kotlin
3551+
[source,kotlin,role="secondary"]
3552+
----
3553+
@Bean
3554+
fun passwordEncoder(): PasswordEncoder {
3555+
return Pbkdf2PasswordEncoder()
3556+
}
3557+
----
3558+
====
3559+
3560+
to:
3561+
3562+
====
3563+
.Java
3564+
[source,java,role="primary"]
3565+
----
3566+
@Bean
3567+
PasswordEncoder passwordEncoder() {
3568+
return Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_5();
3569+
}
3570+
----
3571+
3572+
.Kotlin
3573+
[source,kotlin,role="secondary"]
3574+
----
3575+
@Bean
3576+
fun passwordEncoder(): PasswordEncoder {
3577+
return Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_5()
3578+
}
3579+
----
3580+
====
3581+
3582+
Or, if you have custom settings, change to the constructor that specifies all settings, like so:
3583+
3584+
====
3585+
.Java
3586+
[source,java,role="primary"]
3587+
----
3588+
@Bean
3589+
PasswordEncoder passwordEncoder() {
3590+
PasswordEncoder current = new Pbkdf2PasswordEncoder("mysecret".getBytes(UTF_8), 320000);
3591+
return current;
3592+
}
3593+
----
3594+
3595+
.Kotlin
3596+
[source,kotlin,role="secondary"]
3597+
----
3598+
@Bean
3599+
fun passwordEncoder(): PasswordEncoder {
3600+
val current: PasswordEncoder = Pbkdf2PasswordEncoder("mysecret".getBytes(UTF_8), 320000)
3601+
return current
3602+
}
3603+
----
3604+
====
3605+
3606+
Change them to use the fully-specified constructor, like the following:
3607+
3608+
====
3609+
.Java
3610+
[source,java,role="primary"]
3611+
----
3612+
@Bean
3613+
PasswordEncoder passwordEncoder() {
3614+
PasswordEncoder current = new Pbkdf2PasswordEncoder("mysecret".getBytes(UTF_8), 16, 185000, 256);
3615+
return current;
3616+
}
3617+
----
3618+
3619+
.Kotlin
3620+
[source,kotlin,role="secondary"]
3621+
----
3622+
@Bean
3623+
fun passwordEncoder(): PasswordEncoder {
3624+
val current: PasswordEncoder = Pbkdf2PasswordEncoder("mysecret".getBytes(UTF_8), 16, 185000, 256)
3625+
return current
3626+
}
3627+
----
3628+
====
3629+
3630+
===== Use `DelegatedPasswordEncoder`
3631+
3632+
Once you are not using the deprecated constructor, the next step is to prepare your code to upgrade to the latest standards by using `DelegatedPasswordEncoder`.
3633+
The following code configures the delegating encoder to detect passwords that are using `current` and replace them with the latest:
3634+
3635+
====
3636+
.Java
3637+
[source,java,role="primary"]
3638+
----
3639+
@Bean
3640+
PasswordEncoder passwordEncoder() {
3641+
String prefix = "[email protected]";
3642+
PasswordEncoder current = // ... see previous step
3643+
PasswordEncoder upgraded = Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8();
3644+
DelegatedPasswordEncoder delegating = new DelegatedPasswordEncoder(prefix, Map.of(prefix, upgraded));
3645+
delegating.setDefaultPasswordEncoderFormatches(current);
3646+
return delegating;
3647+
}
3648+
----
3649+
3650+
.Kotlin
3651+
[source,kotlin,role="secondary"]
3652+
----
3653+
@Bean
3654+
fun passwordEncoder(): PasswordEncoder {
3655+
String prefix = "[email protected]"
3656+
PasswordEncoder current = // ... see previous step
3657+
PasswordEncoder upgraded = Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8()
3658+
DelegatedPasswordEncoder delegating = new DelegatedPasswordEncoder(prefix, Map.of(prefix, upgraded))
3659+
delegating.setDefaultPasswordEncoderFormatches(current)
3660+
return delegating
3661+
}
3662+
----
3663+
====
3664+
3665+
==== Update `SCryptPasswordEncoder`
3666+
3667+
If you are xref:features/authentication/password-storage.adoc#authentication-password-storage-scrypt[using `SCryptPasswordEncoder`], the constructors are replaced with static factories that refer to the Spring Security version that the given settings apply to.
3668+
3669+
===== Replace Deprecated Constructor Usage
3670+
3671+
If you use the default constructor, you should begin by changing:
3672+
3673+
====
3674+
.Java
3675+
[source,java,role="primary"]
3676+
----
3677+
@Bean
3678+
PasswordEncoder passwordEncoder() {
3679+
return new SCryptPasswordEncoder();
3680+
}
3681+
----
3682+
3683+
.Kotlin
3684+
[source,kotlin,role="secondary"]
3685+
----
3686+
@Bean
3687+
fun passwordEncoder(): PasswordEncoder {
3688+
return SCryptPasswordEncoder()
3689+
}
3690+
----
3691+
====
3692+
3693+
to:
3694+
3695+
====
3696+
.Java
3697+
[source,java,role="primary"]
3698+
----
3699+
@Bean
3700+
PasswordEncoder passwordEncoder() {
3701+
return SCryptPasswordEncoder.defaultsForSpringSecurity_v4_1();
3702+
}
3703+
----
3704+
3705+
.Kotlin
3706+
[source,kotlin,role="secondary"]
3707+
----
3708+
@Bean
3709+
fun passwordEncoder(): PasswordEncoder {
3710+
return SCryptPasswordEncoder.defaultsForSpringSecurity_v4_1()
3711+
}
3712+
----
3713+
====
3714+
3715+
===== Use `DelegatedPasswordEncoder`
3716+
3717+
Once you are not using the deprecated constructor, the next step is to prepare your code to upgrade to the latest standards by using `DelegatedPasswordEncoder`.
3718+
The following code configures the delegating encoder to detect passwords that are using `current` and replace them with the latest:
3719+
3720+
====
3721+
.Java
3722+
[source,java,role="primary"]
3723+
----
3724+
@Bean
3725+
PasswordEncoder passwordEncoder() {
3726+
String prefix = "[email protected]";
3727+
PasswordEncoder current = // ... see previous step
3728+
PasswordEncoder upgraded = SCryptPasswordEncoder.defaultsForSpringSecurity_v5_8();
3729+
DelegatedPasswordEncoder delegating = new DelegatedPasswordEncoder(prefix, Map.of(prefix, upgraded));
3730+
delegating.setDefaultPasswordEncoderFormatches(current);
3731+
return delegating;
3732+
}
3733+
----
3734+
3735+
.Kotlin
3736+
[source,kotlin,role="secondary"]
3737+
----
3738+
@Bean
3739+
fun passwordEncoder(): PasswordEncoder {
3740+
String prefix = "[email protected]"
3741+
PasswordEncoder current = // ... see previous step
3742+
PasswordEncoder upgraded = SCryptPasswordEncoder.defaultsForSpringSecurity_v5_8()
3743+
DelegatedPasswordEncoder delegating = new DelegatedPasswordEncoder(prefix, Map.of(prefix, upgraded))
3744+
delegating.setDefaultPasswordEncoderFormatches(current)
3745+
return delegating
3746+
}
3747+
----
3748+
====
3749+
3750+
==== Update `Argon2PasswordEncoder`
3751+
3752+
If you are xref:features/authentication/password-storage.adoc#authentication-password-storage-argon2[using `Argon2PasswordEncoder`], the constructors are replaced with static factories that refer to the Spring Security version that the given settings apply to.
3753+
3754+
===== Replace Deprecated Constructor Usage
3755+
3756+
If you use the default constructor, you should begin by changing:
3757+
3758+
====
3759+
.Java
3760+
[source,java,role="primary"]
3761+
----
3762+
@Bean
3763+
PasswordEncoder passwordEncoder() {
3764+
return new Argon2PasswordEncoder();
3765+
}
3766+
----
3767+
3768+
.Kotlin
3769+
[source,kotlin,role="secondary"]
3770+
----
3771+
@Bean
3772+
fun passwordEncoder(): PasswordEncoder {
3773+
return Argon2PasswordEncoder()
3774+
}
3775+
----
3776+
====
3777+
3778+
to:
3779+
3780+
====
3781+
.Java
3782+
[source,java,role="primary"]
3783+
----
3784+
@Bean
3785+
PasswordEncoder passwordEncoder() {
3786+
return Argon2PasswordEncoder.defaultsForSpringSecurity_v5_2();
3787+
}
3788+
----
3789+
3790+
.Kotlin
3791+
[source,kotlin,role="secondary"]
3792+
----
3793+
@Bean
3794+
fun passwordEncoder(): PasswordEncoder {
3795+
return Argon2PasswordEncoder.defaultsForSpringSecurity_v5_2()
3796+
}
3797+
----
3798+
====
3799+
3800+
===== Use `DelegatedPasswordEncoder`
3801+
3802+
Once you are not using the deprecated constructor, the next step is to prepare your code to upgrade to the latest standards by using `DelegatedPasswordEncoder`.
3803+
The following code configures the delegating encoder to detect passwords that are using `current` and replace them with the latest:
3804+
3805+
====
3806+
.Java
3807+
[source,java,role="primary"]
3808+
----
3809+
@Bean
3810+
PasswordEncoder passwordEncoder() {
3811+
String prefix = "[email protected]";
3812+
PasswordEncoder current = // ... see previous step
3813+
PasswordEncoder upgraded = Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8();
3814+
DelegatedPasswordEncoder delegating = new DelegatedPasswordEncoder(prefix, Map.of(prefix, upgraded));
3815+
delegating.setDefaultPasswordEncoderFormatches(current);
3816+
return delegating;
3817+
}
3818+
----
3819+
3820+
.Kotlin
3821+
[source,kotlin,role="secondary"]
3822+
----
3823+
@Bean
3824+
fun passwordEncoder(): PasswordEncoder {
3825+
String prefix = "[email protected]"
3826+
PasswordEncoder current = // ... see previous step
3827+
PasswordEncoder upgraded = Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8()
3828+
DelegatedPasswordEncoder delegating = new DelegatedPasswordEncoder(prefix, Map.of(prefix, upgraded))
3829+
delegating.setDefaultPasswordEncoderFormatches(current)
3830+
return delegating
3831+
}
3832+
----
3833+
====
3834+
35233835
== Reactive
35243836

35253837
=== Use `AuthorizationManager` for Method Security

0 commit comments

Comments
 (0)