Skip to content

Commit 8c708b1

Browse files
committed
Merge branch '3.2.x'
Closes gh-39239
2 parents 686fe84 + 961da4e commit 8c708b1

File tree

4 files changed

+96
-12
lines changed

4 files changed

+96
-12
lines changed

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

+31-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@
2929
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3030
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3131
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
32+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3233
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
3334
import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration;
3435
import org.springframework.boot.autoconfigure.security.SecurityProperties;
@@ -58,13 +59,12 @@
5859
*/
5960
@AutoConfiguration(before = ReactiveSecurityAutoConfiguration.class, after = RSocketMessagingAutoConfiguration.class)
6061
@ConditionalOnClass({ ReactiveAuthenticationManager.class })
61-
@ConditionalOnMissingClass({ "org.springframework.security.oauth2.client.registration.ClientRegistrationRepository",
62-
"org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector" })
6362
@ConditionalOnMissingBean(
6463
value = { ReactiveAuthenticationManager.class, ReactiveUserDetailsService.class,
6564
ReactiveAuthenticationManagerResolver.class },
6665
type = { "org.springframework.security.oauth2.jwt.ReactiveJwtDecoder" })
67-
@Conditional(ReactiveUserDetailsServiceAutoConfiguration.ReactiveUserDetailsServiceCondition.class)
66+
@Conditional({ ReactiveUserDetailsServiceAutoConfiguration.RSocketEnabledOrReactiveWebApplication.class,
67+
ReactiveUserDetailsServiceAutoConfiguration.MissingAlternativeOrUserPropertiesConfigured.class })
6868
@EnableConfigurationProperties(SecurityProperties.class)
6969
public class ReactiveUserDetailsServiceAutoConfiguration {
7070

@@ -98,9 +98,9 @@ private String getOrDeducePassword(SecurityProperties.User user, PasswordEncoder
9898
return NOOP_PASSWORD_PREFIX + password;
9999
}
100100

101-
static class ReactiveUserDetailsServiceCondition extends AnyNestedCondition {
101+
static class RSocketEnabledOrReactiveWebApplication extends AnyNestedCondition {
102102

103-
ReactiveUserDetailsServiceCondition() {
103+
RSocketEnabledOrReactiveWebApplication() {
104104
super(ConfigurationPhase.REGISTER_BEAN);
105105
}
106106

@@ -116,4 +116,29 @@ static class ReactiveWebApplicationCondition {
116116

117117
}
118118

119+
static final class MissingAlternativeOrUserPropertiesConfigured extends AnyNestedCondition {
120+
121+
MissingAlternativeOrUserPropertiesConfigured() {
122+
super(ConfigurationPhase.PARSE_CONFIGURATION);
123+
}
124+
125+
@ConditionalOnMissingClass({
126+
"org.springframework.security.oauth2.client.registration.ClientRegistrationRepository",
127+
"org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector" })
128+
static final class MissingAlternative {
129+
130+
}
131+
132+
@ConditionalOnProperty(prefix = "spring.security.user", name = "name")
133+
static final class NameConfigured {
134+
135+
}
136+
137+
@ConditionalOnProperty(prefix = "spring.security.user", name = "password")
138+
static final class PasswordConfigured {
139+
140+
}
141+
142+
}
143+
119144
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfiguration.java

+32-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,12 +25,16 @@
2525
import org.springframework.beans.factory.ObjectProvider;
2626
import org.springframework.boot.autoconfigure.AutoConfiguration;
2727
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
28+
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
2829
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2930
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3031
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3132
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
33+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3234
import org.springframework.boot.autoconfigure.security.SecurityProperties;
35+
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration.MissingAlternativeOrUserPropertiesConfigured;
3336
import org.springframework.context.annotation.Bean;
37+
import org.springframework.context.annotation.Conditional;
3438
import org.springframework.security.authentication.AuthenticationManager;
3539
import org.springframework.security.authentication.AuthenticationManagerResolver;
3640
import org.springframework.security.authentication.AuthenticationProvider;
@@ -53,9 +57,7 @@
5357
*/
5458
@AutoConfiguration
5559
@ConditionalOnClass(AuthenticationManager.class)
56-
@ConditionalOnMissingClass({ "org.springframework.security.oauth2.client.registration.ClientRegistrationRepository",
57-
"org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector",
58-
"org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository" })
60+
@Conditional(MissingAlternativeOrUserPropertiesConfigured.class)
5961
@ConditionalOnBean(ObjectPostProcessor.class)
6062
@ConditionalOnMissingBean(value = { AuthenticationManager.class, AuthenticationProvider.class, UserDetailsService.class,
6163
AuthenticationManagerResolver.class }, type = "org.springframework.security.oauth2.jwt.JwtDecoder")
@@ -93,4 +95,30 @@ private String getOrDeducePassword(SecurityProperties.User user, PasswordEncoder
9395
return NOOP_PASSWORD_PREFIX + password;
9496
}
9597

98+
static final class MissingAlternativeOrUserPropertiesConfigured extends AnyNestedCondition {
99+
100+
MissingAlternativeOrUserPropertiesConfigured() {
101+
super(ConfigurationPhase.PARSE_CONFIGURATION);
102+
}
103+
104+
@ConditionalOnMissingClass({
105+
"org.springframework.security.oauth2.client.registration.ClientRegistrationRepository",
106+
"org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector",
107+
"org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository" })
108+
static final class MissingAlternative {
109+
110+
}
111+
112+
@ConditionalOnProperty(prefix = "spring.security.user", name = "name")
113+
static final class NameConfigured {
114+
115+
}
116+
117+
@ConditionalOnProperty(prefix = "spring.security.user", name = "password")
118+
static final class PasswordConfigured {
119+
120+
}
121+
122+
}
123+
96124
}

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

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -121,6 +121,18 @@ void doesNotConfigureDefaultUserIfResourceServerIsPresent() {
121121
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ReactiveUserDetailsService.class));
122122
}
123123

124+
@Test
125+
void configuresDefaultUserWhenResourceServerIsPresentAndUsernameIsConfigured() {
126+
this.contextRunner.withPropertyValues("spring.security.user.name=carol")
127+
.run((context) -> assertThat(context).hasSingleBean(ReactiveUserDetailsService.class));
128+
}
129+
130+
@Test
131+
void configuresDefaultUserWhenResourceServerIsPresentAndPasswordIsConfigured() {
132+
this.contextRunner.withPropertyValues("spring.security.user.password=p4ssw0rd")
133+
.run((context) -> assertThat(context).hasSingleBean(ReactiveUserDetailsService.class));
134+
}
135+
124136
@Test
125137
void userDetailsServiceWhenPasswordEncoderAbsentAndDefaultPassword() {
126138
this.contextRunner

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

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,8 +23,10 @@
2323
import org.junit.jupiter.api.extension.ExtendWith;
2424

2525
import org.springframework.boot.autoconfigure.AutoConfigurations;
26+
import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener;
2627
import org.springframework.boot.autoconfigure.security.SecurityProperties;
2728
import org.springframework.boot.context.properties.EnableConfigurationProperties;
29+
import org.springframework.boot.logging.LogLevel;
2830
import org.springframework.boot.test.context.FilteredClassLoader;
2931
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3032
import org.springframework.boot.test.system.CapturedOutput;
@@ -176,6 +178,23 @@ void userDetailsServiceWhenRelyingPartyRegistrationRepositoryPresent() {
176178
.run(((context) -> assertThat(context).doesNotHaveBean(InMemoryUserDetailsManager.class)));
177179
}
178180

181+
@Test
182+
void userDetailsServiceWhenRelyingPartyRegistrationRepositoryPresentAndUsernameConfigured() {
183+
this.contextRunner
184+
.withClassLoader(new FilteredClassLoader(ClientRegistrationRepository.class, OpaqueTokenIntrospector.class))
185+
.withPropertyValues("spring.security.user.name=alice")
186+
.withInitializer(ConditionEvaluationReportLoggingListener.forLogLevel(LogLevel.INFO))
187+
.run(((context) -> assertThat(context).hasSingleBean(InMemoryUserDetailsManager.class)));
188+
}
189+
190+
@Test
191+
void userDetailsServiceWhenRelyingPartyRegistrationRepositoryPresentAndPasswordConfigured() {
192+
this.contextRunner
193+
.withClassLoader(new FilteredClassLoader(ClientRegistrationRepository.class, OpaqueTokenIntrospector.class))
194+
.withPropertyValues("spring.security.user.password=secret")
195+
.run(((context) -> assertThat(context).hasSingleBean(InMemoryUserDetailsManager.class)));
196+
}
197+
179198
private Function<ApplicationContextRunner, ApplicationContextRunner> noOtherFormsOfAuthenticationOnTheClasspath() {
180199
return (contextRunner) -> contextRunner
181200
.withClassLoader(new FilteredClassLoader(ClientRegistrationRepository.class, OpaqueTokenIntrospector.class,

0 commit comments

Comments
 (0)