Skip to content

Commit ff9fde0

Browse files
committed
Polish "Make UserDetailsServiceAutoConfiguration conditional on servlet app"
See gh-43334
1 parent c5d41f1 commit ff9fde0

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java

+48-9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.springframework.boot.autoconfigure.security.SecurityProperties;
2727
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2828
import org.springframework.boot.test.context.FilteredClassLoader;
29+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
30+
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
2931
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
3032
import org.springframework.boot.test.system.CapturedOutput;
3133
import org.springframework.boot.test.system.OutputCaptureExtension;
@@ -57,6 +59,7 @@
5759
* @author Madhura Bhave
5860
* @author HaiTao Zhang
5961
* @author Lasse Wulff
62+
* @author Moritz Halbritter
6063
*/
6164
@ExtendWith(OutputCaptureExtension.class)
6265
class UserDetailsServiceAutoConfigurationTests {
@@ -65,9 +68,31 @@ class UserDetailsServiceAutoConfigurationTests {
6568
.withUserConfiguration(TestSecurityConfiguration.class)
6669
.withConfiguration(AutoConfigurations.of(UserDetailsServiceAutoConfiguration.class));
6770

71+
@Test
72+
void shouldSupplyUserDetailsServiceInServletApp() {
73+
this.contextRunner.with(AuthenticationExclude.servletApp())
74+
.run((context) -> assertThat(context).hasSingleBean(UserDetailsService.class));
75+
}
76+
77+
@Test
78+
void shouldNotSupplyUserDetailsServiceInReactiveApp() {
79+
new ReactiveWebApplicationContextRunner().withUserConfiguration(TestSecurityConfiguration.class)
80+
.withConfiguration(AutoConfigurations.of(UserDetailsServiceAutoConfiguration.class))
81+
.with(AuthenticationExclude.reactiveApp())
82+
.run((context) -> assertThat(context).doesNotHaveBean(UserDetailsService.class));
83+
}
84+
85+
@Test
86+
void shouldNotSupplyUserDetailsServiceInNonWebApp() {
87+
new ApplicationContextRunner().withUserConfiguration(TestSecurityConfiguration.class)
88+
.withConfiguration(AutoConfigurations.of(UserDetailsServiceAutoConfiguration.class))
89+
.with(AuthenticationExclude.noWebApp())
90+
.run((context) -> assertThat(context).doesNotHaveBean(UserDetailsService.class));
91+
}
92+
6893
@Test
6994
void testDefaultUsernamePassword(CapturedOutput output) {
70-
this.contextRunner.with(noOtherFormsOfAuthenticationOnTheClasspath()).run((context) -> {
95+
this.contextRunner.with(AuthenticationExclude.servletApp()).run((context) -> {
7196
UserDetailsService manager = context.getBean(UserDetailsService.class);
7297
assertThat(output).contains("Using generated security password:");
7398
assertThat(manager.loadUserByUsername("user")).isNotNull();
@@ -129,7 +154,7 @@ void defaultUserNotCreatedIfResourceServerWithJWTIsUsed() {
129154

130155
@Test
131156
void userDetailsServiceWhenPasswordEncoderAbsentAndDefaultPassword() {
132-
this.contextRunner.with(noOtherFormsOfAuthenticationOnTheClasspath())
157+
this.contextRunner.with(AuthenticationExclude.servletApp())
133158
.withUserConfiguration(TestSecurityConfiguration.class)
134159
.run(((context) -> {
135160
InMemoryUserDetailsManager userDetailsService = context.getBean(InMemoryUserDetailsManager.class);
@@ -193,14 +218,8 @@ void userDetailsServiceWhenRelyingPartyRegistrationRepositoryPresentAndPasswordC
193218
.run(((context) -> assertThat(context).hasSingleBean(InMemoryUserDetailsManager.class)));
194219
}
195220

196-
private Function<WebApplicationContextRunner, WebApplicationContextRunner> noOtherFormsOfAuthenticationOnTheClasspath() {
197-
return (contextRunner) -> contextRunner
198-
.withClassLoader(new FilteredClassLoader(ClientRegistrationRepository.class, OpaqueTokenIntrospector.class,
199-
RelyingPartyRegistrationRepository.class));
200-
}
201-
202221
private void testPasswordEncoding(Class<?> configClass, String providedPassword, String expectedPassword) {
203-
this.contextRunner.with(noOtherFormsOfAuthenticationOnTheClasspath())
222+
this.contextRunner.with(AuthenticationExclude.servletApp())
204223
.withClassLoader(new FilteredClassLoader(ClientRegistrationRepository.class, OpaqueTokenIntrospector.class,
205224
RelyingPartyRegistrationRepository.class))
206225
.withUserConfiguration(configClass)
@@ -212,6 +231,26 @@ private void testPasswordEncoding(Class<?> configClass, String providedPassword,
212231
}));
213232
}
214233

234+
private static final class AuthenticationExclude {
235+
236+
private static final FilteredClassLoader filteredClassLoader = new FilteredClassLoader(
237+
ClientRegistrationRepository.class, OpaqueTokenIntrospector.class,
238+
RelyingPartyRegistrationRepository.class);
239+
240+
static Function<WebApplicationContextRunner, WebApplicationContextRunner> servletApp() {
241+
return (contextRunner) -> contextRunner.withClassLoader(filteredClassLoader);
242+
}
243+
244+
static Function<ReactiveWebApplicationContextRunner, ReactiveWebApplicationContextRunner> reactiveApp() {
245+
return (contextRunner) -> contextRunner.withClassLoader(filteredClassLoader);
246+
}
247+
248+
static Function<ApplicationContextRunner, ApplicationContextRunner> noWebApp() {
249+
return (contextRunner) -> contextRunner.withClassLoader(filteredClassLoader);
250+
}
251+
252+
}
253+
215254
@Configuration(proxyBeanMethods = false)
216255
static class TestAuthenticationManagerConfiguration {
217256

0 commit comments

Comments
 (0)