1616
1717package org .springframework .security .authentication .dao ;
1818
19+ import java .util .function .Supplier ;
20+
1921import org .springframework .security .authentication .AuthenticationProvider ;
2022import org .springframework .security .authentication .BadCredentialsException ;
2123import org .springframework .security .authentication .InternalAuthenticationServiceException ;
3133import org .springframework .security .crypto .factory .PasswordEncoderFactories ;
3234import org .springframework .security .crypto .password .PasswordEncoder ;
3335import org .springframework .util .Assert ;
36+ import org .springframework .util .function .SingletonSupplier ;
3437
3538/**
3639 * An {@link AuthenticationProvider} implementation that retrieves user details from a
@@ -48,7 +51,8 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
4851 */
4952 private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword" ;
5053
51- private PasswordEncoder passwordEncoder ;
54+ private Supplier <PasswordEncoder > passwordEncoder = SingletonSupplier
55+ .of (PasswordEncoderFactories ::createDelegatingPasswordEncoder );
5256
5357 /**
5458 * The password used to perform {@link PasswordEncoder#matches(CharSequence, String)}
@@ -64,15 +68,25 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
6468
6569 private CompromisedPasswordChecker compromisedPasswordChecker ;
6670
71+ /**
72+ * @deprecated Please provide the {@link UserDetailsService} in the constructor
73+ */
74+ @ Deprecated
6775 public DaoAuthenticationProvider () {
68- this (PasswordEncoderFactories .createDelegatingPasswordEncoder ());
76+ }
77+
78+ public DaoAuthenticationProvider (UserDetailsService userDetailsService ) {
79+ setUserDetailsService (userDetailsService );
6980 }
7081
7182 /**
7283 * Creates a new instance using the provided {@link PasswordEncoder}
7384 * @param passwordEncoder the {@link PasswordEncoder} to use. Cannot be null.
7485 * @since 6.0.3
86+ * @deprecated Please provide the {@link UserDetailsService} in the constructor
87+ * followed by {@link #setPasswordEncoder(PasswordEncoder)} instead
7588 */
89+ @ Deprecated
7690 public DaoAuthenticationProvider (PasswordEncoder passwordEncoder ) {
7791 setPasswordEncoder (passwordEncoder );
7892 }
@@ -87,7 +101,7 @@ protected void additionalAuthenticationChecks(UserDetails userDetails,
87101 .getMessage ("AbstractUserDetailsAuthenticationProvider.badCredentials" , "Bad credentials" ));
88102 }
89103 String presentedPassword = authentication .getCredentials ().toString ();
90- if (!this .passwordEncoder .matches (presentedPassword , userDetails .getPassword ())) {
104+ if (!this .passwordEncoder .get (). matches (presentedPassword , userDetails .getPassword ())) {
91105 this .logger .debug ("Failed to authenticate since password does not match stored value" );
92106 throw new BadCredentialsException (this .messages
93107 .getMessage ("AbstractUserDetailsAuthenticationProvider.badCredentials" , "Bad credentials" ));
@@ -133,24 +147,24 @@ protected Authentication createSuccessAuthentication(Object principal, Authentic
133147 throw new CompromisedPasswordException ("The provided password is compromised, please change your password" );
134148 }
135149 boolean upgradeEncoding = this .userDetailsPasswordService != null
136- && this .passwordEncoder .upgradeEncoding (user .getPassword ());
150+ && this .passwordEncoder .get (). upgradeEncoding (user .getPassword ());
137151 if (upgradeEncoding ) {
138- String newPassword = this .passwordEncoder .encode (presentedPassword );
152+ String newPassword = this .passwordEncoder .get (). encode (presentedPassword );
139153 user = this .userDetailsPasswordService .updatePassword (user , newPassword );
140154 }
141155 return super .createSuccessAuthentication (principal , authentication , user );
142156 }
143157
144158 private void prepareTimingAttackProtection () {
145159 if (this .userNotFoundEncodedPassword == null ) {
146- this .userNotFoundEncodedPassword = this .passwordEncoder .encode (USER_NOT_FOUND_PASSWORD );
160+ this .userNotFoundEncodedPassword = this .passwordEncoder .get (). encode (USER_NOT_FOUND_PASSWORD );
147161 }
148162 }
149163
150164 private void mitigateAgainstTimingAttack (UsernamePasswordAuthenticationToken authentication ) {
151165 if (authentication .getCredentials () != null ) {
152166 String presentedPassword = authentication .getCredentials ().toString ();
153- this .passwordEncoder .matches (presentedPassword , this .userNotFoundEncodedPassword );
167+ this .passwordEncoder .get (). matches (presentedPassword , this .userNotFoundEncodedPassword );
154168 }
155169 }
156170
@@ -163,14 +177,19 @@ private void mitigateAgainstTimingAttack(UsernamePasswordAuthenticationToken aut
163177 */
164178 public void setPasswordEncoder (PasswordEncoder passwordEncoder ) {
165179 Assert .notNull (passwordEncoder , "passwordEncoder cannot be null" );
166- this .passwordEncoder = passwordEncoder ;
180+ this .passwordEncoder = () -> passwordEncoder ;
167181 this .userNotFoundEncodedPassword = null ;
168182 }
169183
170184 protected PasswordEncoder getPasswordEncoder () {
171- return this .passwordEncoder ;
185+ return this .passwordEncoder . get () ;
172186 }
173187
188+ /**
189+ * @param userDetailsService
190+ * @deprecated Please provide the {@link UserDetailsService} in the constructor
191+ */
192+ @ Deprecated
174193 public void setUserDetailsService (UserDetailsService userDetailsService ) {
175194 this .userDetailsService = userDetailsService ;
176195 }
0 commit comments