From bc5e6da23c3499f64fafffc1f13e07e28660e746 Mon Sep 17 00:00:00 2001 From: Tran Ngoc Nhan Date: Fri, 20 Jun 2025 01:51:18 +0700 Subject: [PATCH] Remove deprecated elements from DaoAuthenticationProvider Closes gh-17298 Signed-off-by: Tran Ngoc Nhan --- ...serDetailsServiceBeanDefinitionParser.java | 7 +- ...nticationProviderBeanDefinitionParser.java | 7 +- .../AuthenticationManagerBuilderTests.java | 5 +- .../NamespaceAuthenticationProviderTests.java | 6 +- .../AuthenticationConfigurationTests.java | 5 +- .../RememberMeConfigurerTests.java | 6 +- .../ServletApiConfigurerTests.java | 5 +- .../http/MiscHttpConfigTests-Sec750.xml | 2 +- .../dao/DaoAuthenticationProvider.java | 31 +---- .../dao/DaoAuthenticationProviderTests.java | 120 +++++++----------- .../InMemoryUserDetailsManagerTests.java | 5 +- .../authentication/passwords/index.adoc | 7 +- .../filter-chain-performance-app-context.xml | 6 +- 13 files changed, 76 insertions(+), 136 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/authentication/AbstractUserDetailsServiceBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/authentication/AbstractUserDetailsServiceBeanDefinitionParser.java index 6c530c0142c..ceec421b8f9 100644 --- a/config/src/main/java/org/springframework/security/config/authentication/AbstractUserDetailsServiceBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/authentication/AbstractUserDetailsServiceBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; @@ -73,8 +74,10 @@ private String resolveId(Element element, AbstractBeanDefinition definition, Par if (!StringUtils.hasText(id)) { id = pc.getReaderContext().generateBeanName(definition); } + ValueHolder userDetailsServiceValueHolder = new ValueHolder(new RuntimeBeanReference(id)); + userDetailsServiceValueHolder.setName("userDetailsService"); BeanDefinition container = pc.getContainingBeanDefinition(); - container.getPropertyValues().add("userDetailsService", new RuntimeBeanReference(id)); + container.getConstructorArgumentValues().addGenericArgumentValue(userDetailsServiceValueHolder); } if (StringUtils.hasText(id)) { return id; diff --git a/config/src/main/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParser.java index 794f30d179a..06515877094 100644 --- a/config/src/main/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationProviderBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; @@ -64,7 +65,9 @@ public BeanDefinition parse(Element element, ParserContext pc) { + "elements '" + Elements.USER_SERVICE + "', '" + Elements.JDBC_USER_SERVICE + "' or '" + Elements.LDAP_USER_SERVICE + "'", element); } - authProvider.getPropertyValues().add("userDetailsService", new RuntimeBeanReference(ref)); + ValueHolder userDetailsServiceValueHolder = new ValueHolder(new RuntimeBeanReference(ref)); + userDetailsServiceValueHolder.setName("userDetailsService"); + authProvider.getConstructorArgumentValues().addGenericArgumentValue(userDetailsServiceValueHolder); } else { // Use the child elements to create the UserDetailsService diff --git a/config/src/test/java/org/springframework/security/config/annotation/authentication/AuthenticationManagerBuilderTests.java b/config/src/test/java/org/springframework/security/config/annotation/authentication/AuthenticationManagerBuilderTests.java index dc2690e3bf4..bcc2b362300 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/authentication/AuthenticationManagerBuilderTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/authentication/AuthenticationManagerBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -241,8 +241,7 @@ AuthenticationManager authenticationManager() throws Exception { @Bean AuthenticationProvider authenticationProvider() throws Exception { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setUserDetailsService(userDetailsService()); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService()); return provider; } diff --git a/config/src/test/java/org/springframework/security/config/annotation/authentication/NamespaceAuthenticationProviderTests.java b/config/src/test/java/org/springframework/security/config/annotation/authentication/NamespaceAuthenticationProviderTests.java index 2769903494a..ab9b45747fc 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/authentication/NamespaceAuthenticationProviderTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/authentication/NamespaceAuthenticationProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,9 +74,7 @@ void configure(AuthenticationManagerBuilder auth) { @Bean DaoAuthenticationProvider authenticationProvider() { - DaoAuthenticationProvider result = new DaoAuthenticationProvider(); - result.setUserDetailsService(new InMemoryUserDetailsManager(PasswordEncodedUser.user())); - return result; + return new DaoAuthenticationProvider(new InMemoryUserDetailsManager(PasswordEncodedUser.user())); } } diff --git a/config/src/test/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.java b/config/src/test/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.java index a25e121073b..6a8ac9ea9f4 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -503,8 +503,7 @@ public void configure(AuthenticationManagerBuilder auth) { UserDetails user = User.withUserDetails(PasswordEncodedUser.user()).username("boot").build(); List users = Arrays.asList(user); InMemoryUserDetailsManager inMemory = new InMemoryUserDetailsManager(users); - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setUserDetailsService(inMemory); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(inMemory); auth.authenticationProvider(provider); } diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java index e3cb83f76fd..bbf3ede9820 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -378,8 +378,8 @@ SecurityFilterChain filterChain(HttpSecurity http) throws Exception { @Autowired void configure(AuthenticationManagerBuilder auth) { User user = (User) PasswordEncodedUser.user(); - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setUserDetailsService(new InMemoryUserDetailsManager(Collections.singletonList(user))); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider( + new InMemoryUserDetailsManager(Collections.singletonList(user))); // @formatter:off auth .authenticationProvider(provider); diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurerTests.java index 9c1a47cf90c..f07fb83bccf 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -269,8 +269,7 @@ UserDetailsService userDetailsService() { @Bean AuthenticationManager customAuthenticationManager(UserDetailsService userDetailsService) { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setUserDetailsService(userDetailsService); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService); return provider::authenticate; } diff --git a/config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-Sec750.xml b/config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-Sec750.xml index ffd22cd3129..f122a4bdb55 100644 --- a/config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-Sec750.xml +++ b/config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-Sec750.xml @@ -34,7 +34,7 @@ - + diff --git a/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java b/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java index b22843e0d9c..099b1ab4776 100644 --- a/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java +++ b/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java @@ -68,31 +68,11 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication private CompromisedPasswordChecker compromisedPasswordChecker; - /** - * @deprecated Please provide the {@link UserDetailsService} in the constructor - */ - @Deprecated - public DaoAuthenticationProvider() { - } - 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); + this.userDetailsService = userDetailsService; } @Override - @SuppressWarnings("deprecation") protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { if (authentication.getCredentials() == null) { @@ -185,15 +165,6 @@ protected PasswordEncoder getPasswordEncoder() { return this.passwordEncoder.get(); } - /** - * @param userDetailsService - * @deprecated Please provide the {@link UserDetailsService} in the constructor - */ - @Deprecated - public void setUserDetailsService(UserDetailsService userDetailsService) { - this.userDetailsService = userDetailsService; - } - protected UserDetailsService getUserDetailsService() { return this.userDetailsService; } diff --git a/core/src/test/java/org/springframework/security/authentication/dao/DaoAuthenticationProviderTests.java b/core/src/test/java/org/springframework/security/authentication/dao/DaoAuthenticationProviderTests.java index 36a5d3bcb97..2b780fa9b23 100644 --- a/core/src/test/java/org/springframework/security/authentication/dao/DaoAuthenticationProviderTests.java +++ b/core/src/test/java/org/springframework/security/authentication/dao/DaoAuthenticationProviderTests.java @@ -80,8 +80,7 @@ public class DaoAuthenticationProviderTests { @Test public void testAuthenticateFailsForIncorrectPasswordCase() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("rod", "KOala"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> provider.authenticate(token)); } @@ -89,8 +88,7 @@ public void testAuthenticateFailsForIncorrectPasswordCase() { @Test public void testReceivedBadCredentialsWhenCredentialsNotProvided() { // Test related to SEC-434 - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); UsernamePasswordAuthenticationToken authenticationToken = UsernamePasswordAuthenticationToken .unauthenticated("rod", null); @@ -102,8 +100,7 @@ public void testReceivedBadCredentialsWhenCredentialsNotProvided() { public void testAuthenticateFailsIfAccountExpired() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("peter", "opal"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserPeterAccountExpired()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserPeterAccountExpired()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(AccountExpiredException.class).isThrownBy(() -> provider.authenticate(token)); } @@ -112,16 +109,14 @@ public void testAuthenticateFailsIfAccountExpired() { public void testAuthenticateFailsIfAccountLocked() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("peter", "opal"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserPeterAccountLocked()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserPeterAccountLocked()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(LockedException.class).isThrownBy(() -> provider.authenticate(token)); } @Test public void testAuthenticateFailsIfCredentialsExpired() { - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserPeterCredentialsExpired()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserPeterCredentialsExpired()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(CredentialsExpiredException.class).isThrownBy( () -> provider.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("peter", "opal"))); @@ -135,8 +130,7 @@ public void testAuthenticateFailsIfCredentialsExpired() { public void testAuthenticateFailsIfUserDisabled() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("peter", "opal"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserPeter()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserPeter()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(DisabledException.class).isThrownBy(() -> provider.authenticate(token)); } @@ -144,8 +138,7 @@ public void testAuthenticateFailsIfUserDisabled() { @Test public void testAuthenticateFailsWhenAuthenticationDaoHasBackendFailure() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("rod", "koala"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceSimulateBackendError()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceSimulateBackendError()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(InternalAuthenticationServiceException.class) .isThrownBy(() -> provider.authenticate(token)); @@ -154,8 +147,7 @@ public void testAuthenticateFailsWhenAuthenticationDaoHasBackendFailure() { @Test public void testAuthenticateFailsWithEmptyUsername() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated(null, "koala"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> provider.authenticate(token)); } @@ -164,8 +156,7 @@ public void testAuthenticateFailsWithEmptyUsername() { public void testAuthenticateFailsWithInvalidPassword() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("rod", "INVALID_PASSWORD"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> provider.authenticate(token)); } @@ -174,10 +165,9 @@ public void testAuthenticateFailsWithInvalidPassword() { public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundExceptionFalse() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("INVALID_USER", "koala"); - DaoAuthenticationProvider provider = createProvider(); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setHideUserNotFoundExceptions(false); // we want // UsernameNotFoundExceptions - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(UsernameNotFoundException.class).isThrownBy(() -> provider.authenticate(token)); } @@ -186,9 +176,8 @@ public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundException public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundExceptionsWithDefaultOfTrue() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("INVALID_USER", "koala"); - DaoAuthenticationProvider provider = createProvider(); - assertThat(provider.isHideUserNotFoundExceptions()).isTrue(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + assertThat(createProvider(null).isHideUserNotFoundExceptions()).isTrue(); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> provider.authenticate(token)); } @@ -197,9 +186,8 @@ public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundException public void testAuthenticateFailsWithInvalidUsernameAndChangePasswordEncoder() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("INVALID_USER", "koala"); - DaoAuthenticationProvider provider = createProvider(); - assertThat(provider.isHideUserNotFoundExceptions()).isTrue(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + assertThat(createProvider(null).isHideUserNotFoundExceptions()).isTrue(); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> provider.authenticate(token)); provider.setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()); @@ -209,8 +197,7 @@ public void testAuthenticateFailsWithInvalidUsernameAndChangePasswordEncoder() { @Test public void testAuthenticateFailsWithMixedCaseUsernameIfDefaultChanged() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("RoD", "koala"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> provider.authenticate(token)); } @@ -219,8 +206,7 @@ public void testAuthenticateFailsWithMixedCaseUsernameIfDefaultChanged() { public void testAuthenticates() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("rod", "koala"); token.setDetails("192.168.0.1"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); Authentication result = provider.authenticate(token); if (!(result instanceof UsernamePasswordAuthenticationToken)) { @@ -236,8 +222,7 @@ public void testAuthenticates() { @Test public void testAuthenticatesASecondTime() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("rod", "koala"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); Authentication result = provider.authenticate(token); if (!(result instanceof UsernamePasswordAuthenticationToken)) { @@ -254,8 +239,7 @@ public void testAuthenticatesASecondTime() { @Test public void testAuthenticatesWithForcePrincipalAsString() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("rod", "koala"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setUserCache(new MockUserCache()); provider.setForcePrincipalAsString(true); Authentication result = provider.authenticate(token); @@ -276,9 +260,8 @@ public void authenticateWhenSuccessAndPasswordManagerThenUpdates() { PasswordEncoder encoder = mock(PasswordEncoder.class); UserDetailsService userDetailsService = mock(UserDetailsService.class); UserDetailsPasswordService passwordManager = mock(UserDetailsPasswordService.class); - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService); provider.setPasswordEncoder(encoder); - provider.setUserDetailsService(userDetailsService); provider.setUserDetailsPasswordService(passwordManager); UserDetails user = PasswordEncodedUser.user(); given(encoder.matches(any(), any())).willReturn(true); @@ -298,9 +281,8 @@ public void authenticateWhenBadCredentialsAndPasswordManagerThenNoUpdate() { PasswordEncoder encoder = mock(PasswordEncoder.class); UserDetailsService userDetailsService = mock(UserDetailsService.class); UserDetailsPasswordService passwordManager = mock(UserDetailsPasswordService.class); - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService); provider.setPasswordEncoder(encoder); - provider.setUserDetailsService(userDetailsService); provider.setUserDetailsPasswordService(passwordManager); UserDetails user = PasswordEncodedUser.user(); given(encoder.matches(any(), any())).willReturn(false); @@ -316,9 +298,8 @@ public void authenticateWhenNotUpgradeAndPasswordManagerThenNoUpdate() { PasswordEncoder encoder = mock(PasswordEncoder.class); UserDetailsService userDetailsService = mock(UserDetailsService.class); UserDetailsPasswordService passwordManager = mock(UserDetailsPasswordService.class); - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService); provider.setPasswordEncoder(encoder); - provider.setUserDetailsService(userDetailsService); provider.setUserDetailsPasswordService(passwordManager); UserDetails user = PasswordEncodedUser.user(); given(encoder.matches(any(), any())).willReturn(true); @@ -331,15 +312,14 @@ public void authenticateWhenNotUpgradeAndPasswordManagerThenNoUpdate() { @Test public void testDetectsNullBeingReturnedFromAuthenticationDao() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("rod", "koala"); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceReturnsNull()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceReturnsNull()); assertThatExceptionOfType(AuthenticationServiceException.class).isThrownBy(() -> provider.authenticate(token)) .withMessage("UserDetailsService returned null, which is an interface contract violation"); } @Test public void testGettersSetters() { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(null); provider.setPasswordEncoder(new BCryptPasswordEncoder()); assertThat(provider.getPasswordEncoder().getClass()).isEqualTo(BCryptPasswordEncoder.class); provider.setUserCache(new SpringCacheBasedUserCache(mock(Cache.class))); @@ -354,8 +334,7 @@ public void testGoesBackToAuthenticationDaoToObtainLatestPasswordIfCachedPasswor UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("rod", "koala"); MockUserDetailsServiceUserRod authenticationDao = new MockUserDetailsServiceUserRod(); MockUserCache cache = new MockUserCache(); - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(authenticationDao); + DaoAuthenticationProvider provider = createProvider(authenticationDao); provider.setUserCache(cache); // This will work, as password still "koala" provider.authenticate(token); @@ -373,14 +352,13 @@ public void testGoesBackToAuthenticationDaoToObtainLatestPasswordIfCachedPasswor @Test public void testStartupFailsIfNoAuthenticationDao() throws Exception { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(null); assertThatIllegalArgumentException().isThrownBy(provider::afterPropertiesSet); } @Test public void testStartupFailsIfNoUserCacheSet() throws Exception { - DaoAuthenticationProvider provider = createProvider(); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); assertThat(provider.getUserCache().getClass()).isEqualTo(NullUserCache.class); provider.setUserCache(null); assertThatIllegalArgumentException().isThrownBy(provider::afterPropertiesSet); @@ -388,9 +366,8 @@ public void testStartupFailsIfNoUserCacheSet() throws Exception { @Test public void testStartupSuccess() throws Exception { - DaoAuthenticationProvider provider = createProvider(); UserDetailsService userDetailsService = new MockUserDetailsServiceUserRod(); - provider.setUserDetailsService(userDetailsService); + DaoAuthenticationProvider provider = createProvider(userDetailsService); provider.setUserCache(new MockUserCache()); assertThat(provider.getUserDetailsService()).isEqualTo(userDetailsService); provider.afterPropertiesSet(); @@ -398,7 +375,7 @@ public void testStartupSuccess() throws Exception { @Test public void testSupports() { - DaoAuthenticationProvider provider = createProvider(); + DaoAuthenticationProvider provider = createProvider(null); assertThat(provider.supports(UsernamePasswordAuthenticationToken.class)).isTrue(); assertThat(!provider.supports(TestingAuthenticationToken.class)).isTrue(); } @@ -410,10 +387,9 @@ public void testUserNotFoundEncodesPassword() throws Exception { "koala"); PasswordEncoder encoder = mock(PasswordEncoder.class); given(encoder.encode(anyString())).willReturn("koala"); - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(new MockUserDetailsServiceUserRod()); provider.setHideUserNotFoundExceptions(false); provider.setPasswordEncoder(encoder); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); provider.afterPropertiesSet(); assertThatExceptionOfType(UsernameNotFoundException.class).isThrownBy(() -> provider.authenticate(token)); // ensure encoder invoked w/ non-null strings since PasswordEncoder impls may fail @@ -426,12 +402,11 @@ public void testUserNotFoundBCryptPasswordEncoder() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("missing", "koala"); PasswordEncoder encoder = new BCryptPasswordEncoder(); - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setHideUserNotFoundExceptions(false); - provider.setPasswordEncoder(encoder); MockUserDetailsServiceUserRod userDetailsService = new MockUserDetailsServiceUserRod(); userDetailsService.password = encoder.encode((CharSequence) token.getCredentials()); - provider.setUserDetailsService(userDetailsService); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService); + provider.setHideUserNotFoundExceptions(false); + provider.setPasswordEncoder(encoder); assertThatExceptionOfType(UsernameNotFoundException.class).isThrownBy(() -> provider.authenticate(token)); } @@ -439,16 +414,15 @@ public void testUserNotFoundBCryptPasswordEncoder() { public void testUserNotFoundDefaultEncoder() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("missing", null); - DaoAuthenticationProvider provider = createProvider(); + DaoAuthenticationProvider provider = createProvider(new MockUserDetailsServiceUserRod()); provider.setHideUserNotFoundExceptions(false); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); assertThatExceptionOfType(UsernameNotFoundException.class).isThrownBy(() -> provider.authenticate(token)); } @Test public void constructWhenPasswordEncoderProvidedThenSets() { - DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider( - NoOpPasswordEncoder.getInstance()); + DaoAuthenticationProvider daoAuthenticationProvider = createProvider(null); + daoAuthenticationProvider.setPasswordEncoder(NoOpPasswordEncoder.getInstance()); assertThat(daoAuthenticationProvider.getPasswordEncoder()).isSameAs(NoOpPasswordEncoder.getInstance()); } @@ -463,12 +437,11 @@ public void IGNOREtestSec2056() { UsernamePasswordAuthenticationToken notFoundUser = UsernamePasswordAuthenticationToken .unauthenticated("notFound", "koala"); PasswordEncoder encoder = new BCryptPasswordEncoder(10, new SecureRandom()); - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setHideUserNotFoundExceptions(false); - provider.setPasswordEncoder(encoder); MockUserDetailsServiceUserRod userDetailsService = new MockUserDetailsServiceUserRod(); userDetailsService.password = encoder.encode((CharSequence) foundUser.getCredentials()); - provider.setUserDetailsService(userDetailsService); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService); + provider.setHideUserNotFoundExceptions(false); + provider.setPasswordEncoder(encoder); int sampleSize = 100; List userFoundTimes = new ArrayList<>(sampleSize); for (int i = 0; i < sampleSize; i++) { @@ -500,24 +473,22 @@ public void testUserNotFoundNullCredentials() { UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.unauthenticated("missing", null); PasswordEncoder encoder = mock(PasswordEncoder.class); - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(new MockUserDetailsServiceUserRod()); provider.setHideUserNotFoundExceptions(false); provider.setPasswordEncoder(encoder); - provider.setUserDetailsService(new MockUserDetailsServiceUserRod()); assertThatExceptionOfType(UsernameNotFoundException.class).isThrownBy(() -> provider.authenticate(token)); verify(encoder, times(0)).matches(anyString(), anyString()); } @Test void authenticateWhenPasswordLeakedThenException() { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()); UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); - provider.setUserDetailsService(withUsers(user)); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(withUsers(user)); + provider.setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()); provider.setCompromisedPasswordChecker(new TestCompromisedPasswordChecker()); assertThatExceptionOfType(CompromisedPasswordException.class).isThrownBy( () -> provider.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("user", "password"))) @@ -526,14 +497,13 @@ void authenticateWhenPasswordLeakedThenException() { @Test void authenticateWhenPasswordNotLeakedThenNoException() { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()); UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("strongpassword") .roles("USER") .build(); - provider.setUserDetailsService(withUsers(user)); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(withUsers(user)); + provider.setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()); provider.setCompromisedPasswordChecker(new TestCompromisedPasswordChecker()); Authentication authentication = provider .authenticate(UsernamePasswordAuthenticationToken.unauthenticated("user", "strongpassword")); @@ -544,8 +514,8 @@ private UserDetailsService withUsers(UserDetails... users) { return new InMemoryUserDetailsManager(users); } - private DaoAuthenticationProvider createProvider() { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + private DaoAuthenticationProvider createProvider(UserDetailsService userDetailsService) { + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService); provider.setPasswordEncoder(NoOpPasswordEncoder.getInstance()); return provider; } diff --git a/core/src/test/java/org/springframework/security/provisioning/InMemoryUserDetailsManagerTests.java b/core/src/test/java/org/springframework/security/provisioning/InMemoryUserDetailsManagerTests.java index 9791c2daf5a..9c97f1a51a7 100644 --- a/core/src/test/java/org/springframework/security/provisioning/InMemoryUserDetailsManagerTests.java +++ b/core/src/test/java/org/springframework/security/provisioning/InMemoryUserDetailsManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -167,8 +167,7 @@ void authenticateWhenInvalidMissingOrMalformedIdThenException(String username, S UserDetails user = User.builder().username(username).password(password).roles("USER").build(); InMemoryUserDetailsManager userManager = new InMemoryUserDetailsManager(user); - DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); - authenticationProvider.setUserDetailsService(userManager); + DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(userManager); authenticationProvider.setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()); AuthenticationManager authManager = new ProviderManager(authenticationProvider); diff --git a/docs/modules/ROOT/pages/servlet/authentication/passwords/index.adoc b/docs/modules/ROOT/pages/servlet/authentication/passwords/index.adoc index f52e95c4c58..7c0d7c2a76b 100644 --- a/docs/modules/ROOT/pages/servlet/authentication/passwords/index.adoc +++ b/docs/modules/ROOT/pages/servlet/authentication/passwords/index.adoc @@ -185,7 +185,7 @@ XML:: class="org.springframework.security.authentication.ProviderManager"> - + @@ -416,8 +416,7 @@ public class SecurityConfig { } private AuthenticationManager authenticationManager() { - DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); - authenticationProvider.setUserDetailsService(userDetailsService()); + DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(userDetailsService()); authenticationProvider.setPasswordEncoder(passwordEncoder()); ProviderManager providerManager = new ProviderManager(authenticationProvider); @@ -456,7 +455,7 @@ XML:: class="org.springframework.security.authentication.ProviderManager"> - + diff --git a/itest/context/src/integration-test/resources/filter-chain-performance-app-context.xml b/itest/context/src/integration-test/resources/filter-chain-performance-app-context.xml index 7b6ac0c6561..1da4cfbe67c 100644 --- a/itest/context/src/integration-test/resources/filter-chain-performance-app-context.xml +++ b/itest/context/src/integration-test/resources/filter-chain-performance-app-context.xml @@ -25,9 +25,9 @@ - - - + + +