Skip to content

Commit b9f3a28

Browse files
committed
Add UserDetailsService Constructor
Closes gh-15973
1 parent f45cc22 commit b9f3a28

File tree

5 files changed

+36
-25
lines changed

5 files changed

+36
-25
lines changed

config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/InitializeUserDetailsBeanManagerConfigurer.java

+2-6
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,10 @@ else if (beanNames.length > 1) {
9595
PasswordEncoder passwordEncoder = getBeanOrNull(PasswordEncoder.class);
9696
UserDetailsPasswordService passwordManager = getBeanOrNull(UserDetailsPasswordService.class);
9797
CompromisedPasswordChecker passwordChecker = getBeanOrNull(CompromisedPasswordChecker.class);
98-
DaoAuthenticationProvider provider;
98+
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService);
9999
if (passwordEncoder != null) {
100-
provider = new DaoAuthenticationProvider(passwordEncoder);
100+
provider.setPasswordEncoder(passwordEncoder);
101101
}
102-
else {
103-
provider = new DaoAuthenticationProvider();
104-
}
105-
provider.setUserDetailsService(userDetailsService);
106102
if (passwordManager != null) {
107103
provider.setUserDetailsPasswordService(passwordManager);
108104
}

config/src/main/java/org/springframework/security/config/annotation/authentication/configurers/userdetails/AbstractDaoAuthenticationConfigurer.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
public abstract class AbstractDaoAuthenticationConfigurer<B extends ProviderManagerBuilder<B>, C extends AbstractDaoAuthenticationConfigurer<B, C, U>, U extends UserDetailsService>
3737
extends UserDetailsAwareConfigurer<B, U> {
3838

39-
private DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
39+
private DaoAuthenticationProvider provider;
4040

4141
private final U userDetailsService;
4242

@@ -46,7 +46,7 @@ public abstract class AbstractDaoAuthenticationConfigurer<B extends ProviderMana
4646
*/
4747
AbstractDaoAuthenticationConfigurer(U userDetailsService) {
4848
this.userDetailsService = userDetailsService;
49-
this.provider.setUserDetailsService(userDetailsService);
49+
this.provider = new DaoAuthenticationProvider(userDetailsService);
5050
if (userDetailsService instanceof UserDetailsPasswordService) {
5151
this.provider.setUserDetailsPasswordService((UserDetailsPasswordService) userDetailsService);
5252
}

config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerFactoryBean.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ public AuthenticationManager getObject() throws Exception {
6565
if (uds == null) {
6666
throw new NoSuchBeanDefinitionException(BeanIds.AUTHENTICATION_MANAGER, MISSING_BEAN_ERROR_MESSAGE);
6767
}
68-
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
69-
provider.setUserDetailsService(uds);
68+
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(uds);
7069
PasswordEncoder passwordEncoder = this.bf.getBeanProvider(PasswordEncoder.class).getIfUnique();
7170
if (passwordEncoder != null) {
7271
provider.setPasswordEncoder(passwordEncoder);

core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java

+28-9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.security.authentication.dao;
1818

19+
import java.util.function.Supplier;
20+
1921
import org.springframework.security.authentication.AuthenticationProvider;
2022
import org.springframework.security.authentication.BadCredentialsException;
2123
import org.springframework.security.authentication.InternalAuthenticationServiceException;
@@ -31,6 +33,7 @@
3133
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
3234
import org.springframework.security.crypto.password.PasswordEncoder;
3335
import 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
}

docs/modules/ROOT/pages/servlet/authentication/passwords/index.adoc

+3-6
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,7 @@ public class SecurityConfig {
148148
public AuthenticationManager authenticationManager(
149149
UserDetailsService userDetailsService,
150150
PasswordEncoder passwordEncoder) {
151-
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
152-
authenticationProvider.setUserDetailsService(userDetailsService);
151+
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(userDetailsService);
153152
authenticationProvider.setPasswordEncoder(passwordEncoder);
154153
155154
return new ProviderManager(authenticationProvider);
@@ -229,8 +228,7 @@ class SecurityConfig {
229228
fun authenticationManager(
230229
userDetailsService: UserDetailsService,
231230
passwordEncoder: PasswordEncoder): AuthenticationManager {
232-
val authenticationProvider = DaoAuthenticationProvider()
233-
authenticationProvider.setUserDetailsService(userDetailsService)
231+
val authenticationProvider = DaoAuthenticationProvider(userDetailsService)
234232
authenticationProvider.setPasswordEncoder(passwordEncoder)
235233
236234
return ProviderManager(authenticationProvider)
@@ -501,8 +499,7 @@ class SecurityConfig {
501499
502500
@Bean
503501
fun authenticationManager(): AuthenticationManager {
504-
val authenticationProvider = DaoAuthenticationProvider()
505-
authenticationProvider.setUserDetailsService(userDetailsService())
502+
val authenticationProvider = DaoAuthenticationProvider(userDetailsService())
506503
authenticationProvider.setPasswordEncoder(passwordEncoder())
507504
508505
val providerManager = ProviderManager(authenticationProvider)

0 commit comments

Comments
 (0)