diff --git a/config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/InitializeUserDetailsBeanManagerConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/InitializeUserDetailsBeanManagerConfigurer.java index 8e4dda56f88..2a78df913a5 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/InitializeUserDetailsBeanManagerConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/InitializeUserDetailsBeanManagerConfigurer.java @@ -96,14 +96,10 @@ else if (userDetailsServices.size() > 1) { PasswordEncoder passwordEncoder = getBeanOrNull(PasswordEncoder.class); UserDetailsPasswordService passwordManager = getBeanOrNull(UserDetailsPasswordService.class); CompromisedPasswordChecker passwordChecker = getBeanOrNull(CompromisedPasswordChecker.class); - DaoAuthenticationProvider provider; + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService); if (passwordEncoder != null) { - provider = new DaoAuthenticationProvider(passwordEncoder); + provider.setPasswordEncoder(passwordEncoder); } - else { - provider = new DaoAuthenticationProvider(); - } - provider.setUserDetailsService(userDetailsService); if (passwordManager != null) { provider.setUserDetailsPasswordService(passwordManager); } diff --git a/config/src/main/java/org/springframework/security/config/annotation/authentication/configurers/userdetails/AbstractDaoAuthenticationConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/authentication/configurers/userdetails/AbstractDaoAuthenticationConfigurer.java index b8595db8bd1..740affa33ea 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/authentication/configurers/userdetails/AbstractDaoAuthenticationConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/authentication/configurers/userdetails/AbstractDaoAuthenticationConfigurer.java @@ -36,7 +36,7 @@ public abstract class AbstractDaoAuthenticationConfigurer, C extends AbstractDaoAuthenticationConfigurer, U extends UserDetailsService> extends UserDetailsAwareConfigurer { - private DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + private DaoAuthenticationProvider provider; private final U userDetailsService; @@ -46,7 +46,7 @@ public abstract class AbstractDaoAuthenticationConfigurer passwordEncoder = SingletonSupplier + .of(PasswordEncoderFactories::createDelegatingPasswordEncoder); /** * The password used to perform {@link PasswordEncoder#matches(CharSequence, String)} @@ -64,15 +68,25 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication private CompromisedPasswordChecker compromisedPasswordChecker; + /** + * @deprecated Please provide the {@link UserDetailsService} in the constructor + */ + @Deprecated public DaoAuthenticationProvider() { - this(PasswordEncoderFactories.createDelegatingPasswordEncoder()); + } + + public DaoAuthenticationProvider(UserDetailsService userDetailsService) { + setUserDetailsService(userDetailsService); } /** * Creates a new instance using the provided {@link PasswordEncoder} * @param passwordEncoder the {@link PasswordEncoder} to use. Cannot be null. * @since 6.0.3 + * @deprecated Please provide the {@link UserDetailsService} in the constructor + * followed by {@link #setPasswordEncoder(PasswordEncoder)} instead */ + @Deprecated public DaoAuthenticationProvider(PasswordEncoder passwordEncoder) { setPasswordEncoder(passwordEncoder); } @@ -87,7 +101,7 @@ protected void additionalAuthenticationChecks(UserDetails userDetails, .getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); } String presentedPassword = authentication.getCredentials().toString(); - if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { + if (!this.passwordEncoder.get().matches(presentedPassword, userDetails.getPassword())) { this.logger.debug("Failed to authenticate since password does not match stored value"); throw new BadCredentialsException(this.messages .getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); @@ -133,9 +147,9 @@ protected Authentication createSuccessAuthentication(Object principal, Authentic throw new CompromisedPasswordException("The provided password is compromised, please change your password"); } boolean upgradeEncoding = this.userDetailsPasswordService != null - && this.passwordEncoder.upgradeEncoding(user.getPassword()); + && this.passwordEncoder.get().upgradeEncoding(user.getPassword()); if (upgradeEncoding) { - String newPassword = this.passwordEncoder.encode(presentedPassword); + String newPassword = this.passwordEncoder.get().encode(presentedPassword); user = this.userDetailsPasswordService.updatePassword(user, newPassword); } return super.createSuccessAuthentication(principal, authentication, user); @@ -143,14 +157,14 @@ protected Authentication createSuccessAuthentication(Object principal, Authentic private void prepareTimingAttackProtection() { if (this.userNotFoundEncodedPassword == null) { - this.userNotFoundEncodedPassword = this.passwordEncoder.encode(USER_NOT_FOUND_PASSWORD); + this.userNotFoundEncodedPassword = this.passwordEncoder.get().encode(USER_NOT_FOUND_PASSWORD); } } private void mitigateAgainstTimingAttack(UsernamePasswordAuthenticationToken authentication) { if (authentication.getCredentials() != null) { String presentedPassword = authentication.getCredentials().toString(); - this.passwordEncoder.matches(presentedPassword, this.userNotFoundEncodedPassword); + this.passwordEncoder.get().matches(presentedPassword, this.userNotFoundEncodedPassword); } } @@ -163,14 +177,19 @@ private void mitigateAgainstTimingAttack(UsernamePasswordAuthenticationToken aut */ public void setPasswordEncoder(PasswordEncoder passwordEncoder) { Assert.notNull(passwordEncoder, "passwordEncoder cannot be null"); - this.passwordEncoder = passwordEncoder; + this.passwordEncoder = () -> passwordEncoder; this.userNotFoundEncodedPassword = null; } protected PasswordEncoder getPasswordEncoder() { - return this.passwordEncoder; + return this.passwordEncoder.get(); } + /** + * @param userDetailsService + * @deprecated Please provide the {@link UserDetailsService} in the constructor + */ + @Deprecated public void setUserDetailsService(UserDetailsService userDetailsService) { this.userDetailsService = userDetailsService; } diff --git a/docs/modules/ROOT/pages/servlet/authentication/passwords/index.adoc b/docs/modules/ROOT/pages/servlet/authentication/passwords/index.adoc index b13cdb615d8..f52e95c4c58 100644 --- a/docs/modules/ROOT/pages/servlet/authentication/passwords/index.adoc +++ b/docs/modules/ROOT/pages/servlet/authentication/passwords/index.adoc @@ -148,8 +148,7 @@ public class SecurityConfig { public AuthenticationManager authenticationManager( UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) { - DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); - authenticationProvider.setUserDetailsService(userDetailsService); + DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(userDetailsService); authenticationProvider.setPasswordEncoder(passwordEncoder); return new ProviderManager(authenticationProvider); @@ -229,8 +228,7 @@ class SecurityConfig { fun authenticationManager( userDetailsService: UserDetailsService, passwordEncoder: PasswordEncoder): AuthenticationManager { - val authenticationProvider = DaoAuthenticationProvider() - authenticationProvider.setUserDetailsService(userDetailsService) + val authenticationProvider = DaoAuthenticationProvider(userDetailsService) authenticationProvider.setPasswordEncoder(passwordEncoder) return ProviderManager(authenticationProvider) @@ -501,8 +499,7 @@ class SecurityConfig { @Bean fun authenticationManager(): AuthenticationManager { - val authenticationProvider = DaoAuthenticationProvider() - authenticationProvider.setUserDetailsService(userDetailsService()) + val authenticationProvider = DaoAuthenticationProvider(userDetailsService()) authenticationProvider.setPasswordEncoder(passwordEncoder()) val providerManager = ProviderManager(authenticationProvider)