From 31cdfd524e24a1a08d2687b8299098088f5bdf8d Mon Sep 17 00:00:00 2001 From: Bartosz Jaszczak Date: Fri, 15 Oct 2021 13:58:15 +0200 Subject: [PATCH 1/2] Make UserDetailsService back off with AuthManagerResolver bean See gh-28361 --- .../UserDetailsServiceAutoConfiguration.java | 4 +++- ...rDetailsServiceAutoConfigurationTests.java | 22 ++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) 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 91d2d12821..75aab597b1 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 1348a54bb1..8c3b5332de 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); + } + + } + } From 9b77151caa214c9ba92ac2769dde913d8d93e88d Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 19 Oct 2021 16:20:31 +0100 Subject: [PATCH 2/2] Polish "Make UserDetailsService back off with AuthManagerResolver bean" See gh-28361 --- .../UserDetailsServiceAutoConfiguration.java | 2 +- ...rDetailsServiceAutoConfigurationTests.java | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) 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 75aab597b1..32830c28c6 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2021 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. 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 8c3b5332de..96a00518ad 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2021 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. @@ -30,7 +30,12 @@ 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.*; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationManagerResolver; +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.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -79,6 +84,12 @@ class UserDetailsServiceAutoConfigurationTests { }); } + @Test + void defaultUserNotCreatedIfAuthenticationManagerResolverBeanPresent(CapturedOutput output) { + this.contextRunner.withUserConfiguration(TestAuthenticationManagerResolverConfiguration.class) + .run((context) -> assertThat(output).doesNotContain("Using generated security password: ")); + } + @Test void defaultUserNotCreatedIfUserDetailsServiceBeanPresent(CapturedOutput output) { this.contextRunner.withUserConfiguration(TestUserDetailsServiceConfiguration.class).run((context) -> { @@ -151,12 +162,6 @@ 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) -> { @@ -272,7 +277,7 @@ class UserDetailsServiceAutoConfigurationTests { static class TestAuthenticationManagerResolverConfiguration { @Bean - AuthenticationManagerResolver myAuthenticationManagerResolver() { + AuthenticationManagerResolver authenticationManagerResolver() { return mock(AuthenticationManagerResolver.class); }