diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java index 91d2d128210..75aab597b19 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java @@ -32,6 +32,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationManagerResolver; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.config.annotation.ObjectPostProcessor; import org.springframework.security.core.userdetails.User; @@ -56,7 +57,8 @@ import org.springframework.util.StringUtils; @ConditionalOnClass(AuthenticationManager.class) @ConditionalOnBean(ObjectPostProcessor.class) @ConditionalOnMissingBean( - value = { AuthenticationManager.class, AuthenticationProvider.class, UserDetailsService.class }, + value = { AuthenticationManager.class, AuthenticationProvider.class, UserDetailsService.class, + AuthenticationManagerResolver.class }, type = { "org.springframework.security.oauth2.jwt.JwtDecoder", "org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector" }) public class UserDetailsServiceAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java index 1348a54bb10..8c3b5332def 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java @@ -30,11 +30,7 @@ import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.authentication.ProviderManager; -import org.springframework.security.authentication.TestingAuthenticationProvider; -import org.springframework.security.authentication.TestingAuthenticationToken; +import org.springframework.security.authentication.*; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -155,6 +151,12 @@ class UserDetailsServiceAutoConfigurationTests { .run(((context) -> assertThat(output).doesNotContain("Using generated security password: "))); } + @Test + void userDetailsServiceShouldNotBePresentWhenAuthenticationManagerResolverBeanIsPresent() { + this.contextRunner.withUserConfiguration(TestAuthenticationManagerResolverConfiguration.class) + .run(((context) -> assertThat(context).doesNotHaveBean(InMemoryUserDetailsManager.class))); + } + private void testPasswordEncoding(Class configClass, String providedPassword, String expectedPassword) { this.contextRunner.withUserConfiguration(configClass) .withPropertyValues("spring.security.user.password=" + providedPassword).run(((context) -> { @@ -266,4 +268,14 @@ class UserDetailsServiceAutoConfigurationTests { } + @Configuration(proxyBeanMethods = false) + static class TestAuthenticationManagerResolverConfiguration { + + @Bean + AuthenticationManagerResolver myAuthenticationManagerResolver() { + return mock(AuthenticationManagerResolver.class); + } + + } + }