Skip to content

Commit e7b14f1

Browse files
Making ReactiveUserDetailsServiceAutoConfiguration conditional
The UserDetailsServiceAutoConfiguration is only to be active in a reactive web application See gh-43345
1 parent 4421fa4 commit e7b14f1

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveUserDetailsServiceAutoConfiguration.java

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
3232
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3333
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
34+
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
3435
import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration;
3536
import org.springframework.boot.autoconfigure.security.SecurityProperties;
3637
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -55,6 +56,7 @@
5556
* {@link ReactiveAuthenticationManagerResolver}.
5657
*
5758
* @author Madhura Bhave
59+
* @author Lasse Wulff
5860
* @since 2.0.0
5961
*/
6062
@AutoConfiguration(before = ReactiveSecurityAutoConfiguration.class, after = RSocketMessagingAutoConfiguration.class)
@@ -65,6 +67,7 @@
6567
type = { "org.springframework.security.oauth2.jwt.ReactiveJwtDecoder" })
6668
@Conditional({ ReactiveUserDetailsServiceAutoConfiguration.RSocketEnabledOrReactiveWebApplication.class,
6769
ReactiveUserDetailsServiceAutoConfiguration.MissingAlternativeOrUserPropertiesConfigured.class })
70+
@ConditionalOnWebApplication(type = Type.REACTIVE)
6871
@EnableConfigurationProperties(SecurityProperties.class)
6972
public class ReactiveUserDetailsServiceAutoConfiguration {
7073

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveUserDetailsServiceAutoConfigurationTests.java

+47-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.autoconfigure.security.reactive;
1818

1919
import java.time.Duration;
20+
import java.util.function.Function;
2021

2122
import org.junit.jupiter.api.Test;
2223

@@ -28,6 +29,7 @@
2829
import org.springframework.boot.test.context.FilteredClassLoader;
2930
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3031
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
32+
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
3133
import org.springframework.context.annotation.Bean;
3234
import org.springframework.context.annotation.Configuration;
3335
import org.springframework.context.annotation.Import;
@@ -52,12 +54,36 @@
5254
*
5355
* @author Madhura Bhave
5456
* @author HaiTao Zhang
57+
* @author Lasse Wulff
5558
*/
5659
class ReactiveUserDetailsServiceAutoConfigurationTests {
5760

5861
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()
5962
.withConfiguration(AutoConfigurations.of(ReactiveUserDetailsServiceAutoConfiguration.class));
6063

64+
@Test
65+
void shouldSupplyUserDetailsServiceInReactiveApp() {
66+
this.contextRunner.withUserConfiguration(TestSecurityConfiguration.class)
67+
.with(AuthenticationExclude.reactiveApp())
68+
.run((context) -> assertThat(context).hasSingleBean(ReactiveUserDetailsService.class));
69+
}
70+
71+
@Test
72+
void shouldNotSupplyUserDetailsServiceInServletApp() {
73+
new WebApplicationContextRunner()
74+
.withConfiguration(AutoConfigurations.of(ReactiveUserDetailsServiceAutoConfiguration.class))
75+
.with(AuthenticationExclude.servletApp())
76+
.run((context) -> assertThat(context).doesNotHaveBean(ReactiveUserDetailsService.class));
77+
}
78+
79+
@Test
80+
void shouldNotSupplyUserDetailsServiceInNonWebApp() {
81+
new ApplicationContextRunner()
82+
.withConfiguration(AutoConfigurations.of(ReactiveUserDetailsServiceAutoConfiguration.class))
83+
.with(AuthenticationExclude.noWebApp())
84+
.run((context) -> assertThat(context).doesNotHaveBean(ReactiveUserDetailsService.class));
85+
}
86+
6187
@Test
6288
void configuresADefaultUser() {
6389
this.contextRunner
@@ -72,7 +98,7 @@ void configuresADefaultUser() {
7298

7399
@Test
74100
void userDetailsServiceWhenRSocketConfigured() {
75-
new ApplicationContextRunner()
101+
this.contextRunner
76102
.withClassLoader(
77103
new FilteredClassLoader(ClientRegistrationRepository.class, ReactiveOpaqueTokenIntrospector.class))
78104
.withConfiguration(AutoConfigurations.of(ReactiveUserDetailsServiceAutoConfiguration.class,
@@ -98,7 +124,7 @@ void doesNotConfigureDefaultUserIfUserDetailsServiceAvailable() {
98124
void doesNotConfigureDefaultUserIfAuthenticationManagerAvailable() {
99125
this.contextRunner.withUserConfiguration(AuthenticationManagerConfig.class, TestSecurityConfiguration.class)
100126
.withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class))
101-
.run((context) -> assertThat(context).getBean(ReactiveUserDetailsService.class).isNull());
127+
.run((context) -> assertThat(context).doesNotHaveBean(ReactiveUserDetailsService.class));
102128
}
103129

104130
@Test
@@ -175,6 +201,25 @@ private void testPasswordEncoding(Class<?> configClass, String providedPassword,
175201
}));
176202
}
177203

204+
private static final class AuthenticationExclude {
205+
206+
private static final FilteredClassLoader filteredClassLoader = new FilteredClassLoader(
207+
ClientRegistrationRepository.class, ReactiveOpaqueTokenIntrospector.class);
208+
209+
static Function<WebApplicationContextRunner, WebApplicationContextRunner> servletApp() {
210+
return (contextRunner) -> contextRunner.withClassLoader(filteredClassLoader);
211+
}
212+
213+
static Function<ReactiveWebApplicationContextRunner, ReactiveWebApplicationContextRunner> reactiveApp() {
214+
return (contextRunner) -> contextRunner.withClassLoader(filteredClassLoader);
215+
}
216+
217+
static Function<ApplicationContextRunner, ApplicationContextRunner> noWebApp() {
218+
return (contextRunner) -> contextRunner.withClassLoader(filteredClassLoader);
219+
}
220+
221+
}
222+
178223
@Configuration(proxyBeanMethods = false)
179224
@EnableWebFluxSecurity
180225
@EnableConfigurationProperties(SecurityProperties.class)

0 commit comments

Comments
 (0)