Skip to content

Commit 05158e7

Browse files
committed
Creates TestEnableWebfluxSecurityAutoConfiguration
See spring-projects/spring-boot#37504 Adds @EnableWebFluxSecurity and copied MapReactiveUserDetailsService beans from boot.
1 parent 6225e23 commit 05158e7

File tree

4 files changed

+85
-14
lines changed

4 files changed

+85
-14
lines changed

spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/ratelimit/PrincipalNameKeyResolverIntegrationTests.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@
3737
import org.springframework.context.annotation.Bean;
3838
import org.springframework.context.annotation.Primary;
3939
import org.springframework.security.config.web.server.ServerHttpSecurity;
40-
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
41-
import org.springframework.security.core.userdetails.User;
42-
import org.springframework.security.core.userdetails.UserDetails;
4340
import org.springframework.security.web.server.SecurityWebFilterChain;
4441
import org.springframework.test.context.ActiveProfiles;
4542
import org.springframework.test.util.TestSocketUtils;
@@ -52,7 +49,9 @@
5249
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT;
5350
import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.basicAuthentication;
5451

55-
@SpringBootTest(webEnvironment = DEFINED_PORT)
52+
@SpringBootTest(webEnvironment = DEFINED_PORT,
53+
properties = { "spring.security.user.name=user", "spring.security.user.password={noop}password",
54+
"spring.security.user.roles=USER" })
5655
@ActiveProfiles("principalname")
5756
public class PrincipalNameKeyResolverIntegrationTests {
5857

@@ -120,12 +119,6 @@ SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
120119
.permitAll().and().build();
121120
}
122121

123-
@Bean
124-
public MapReactiveUserDetailsService reactiveUserDetailsService() {
125-
UserDetails user = User.withUsername("user").password("{noop}password").roles("USER").build();
126-
return new MapReactiveUserDetailsService(user);
127-
}
128-
129122
class MyRateLimiter implements RateLimiter<Object> {
130123

131124
private HashMap<String, Object> map = new HashMap<>();

spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/PermitAllSecurityConfiguration.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,10 @@
1818

1919
import org.springframework.context.annotation.Bean;
2020
import org.springframework.context.annotation.Configuration;
21-
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
2221
import org.springframework.security.config.web.server.ServerHttpSecurity;
2322
import org.springframework.security.web.server.SecurityWebFilterChain;
2423

2524
@Configuration(proxyBeanMethods = false)
26-
// TODO: remove when below is fixed
27-
// https://github.com/spring-projects/spring-boot/commit/ee9c74556d45b39f097aff8a5fa65c6394d060b5
28-
@EnableWebFluxSecurity
2925
public class PermitAllSecurityConfiguration {
3026

3127
@Bean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2013-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.gateway.test;
18+
19+
import java.util.List;
20+
import java.util.regex.Pattern;
21+
22+
import org.apache.commons.logging.Log;
23+
import org.apache.commons.logging.LogFactory;
24+
25+
import org.springframework.beans.factory.ObjectProvider;
26+
import org.springframework.boot.autoconfigure.AutoConfiguration;
27+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
28+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
29+
import org.springframework.boot.autoconfigure.security.SecurityProperties;
30+
import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration;
31+
import org.springframework.context.annotation.Bean;
32+
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
33+
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
34+
import org.springframework.security.core.userdetails.User;
35+
import org.springframework.security.core.userdetails.UserDetails;
36+
import org.springframework.security.crypto.password.PasswordEncoder;
37+
import org.springframework.util.StringUtils;
38+
import org.springframework.web.reactive.DispatcherHandler;
39+
40+
/*
41+
See https://github.com/spring-projects/spring-boot/issues/37504.
42+
Because gateway has normal spring security and spring security oauth 2
43+
we need an explicit @EnableWebFluxSecurity and a ReactiveUserDetailsService
44+
*/
45+
@AutoConfiguration(before = ReactiveSecurityAutoConfiguration.class)
46+
@ConditionalOnClass(DispatcherHandler.class)
47+
@EnableWebFluxSecurity
48+
public class TestEnableWebfluxSecurityAutoConfiguration {
49+
50+
private static final String NOOP_PASSWORD_PREFIX = "{noop}";
51+
52+
private static final Pattern PASSWORD_ALGORITHM_PATTERN = Pattern.compile("^\\{.+}.*$");
53+
54+
private static final Log logger = LogFactory.getLog(TestEnableWebfluxSecurityAutoConfiguration.class);
55+
56+
@Bean
57+
@ConditionalOnMissingBean
58+
public MapReactiveUserDetailsService reactiveUserDetailsService(SecurityProperties properties,
59+
ObjectProvider<PasswordEncoder> passwordEncoder) {
60+
SecurityProperties.User user = properties.getUser();
61+
UserDetails userDetails = getUserDetails(user, getOrDeducePassword(user, passwordEncoder.getIfAvailable()));
62+
return new MapReactiveUserDetailsService(userDetails);
63+
}
64+
65+
private UserDetails getUserDetails(SecurityProperties.User user, String password) {
66+
List<String> roles = user.getRoles();
67+
return User.withUsername(user.getName()).password(password).roles(StringUtils.toStringArray(roles)).build();
68+
}
69+
70+
private String getOrDeducePassword(SecurityProperties.User user, PasswordEncoder encoder) {
71+
String password = user.getPassword();
72+
if (user.isPasswordGenerated()) {
73+
logger.info(String.format("%n%nUsing generated security password: %s%n", user.getPassword()));
74+
}
75+
if (encoder != null || PASSWORD_ALGORITHM_PATTERN.matcher(password).matches()) {
76+
return password;
77+
}
78+
return NOOP_PASSWORD_PREFIX + password;
79+
}
80+
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.springframework.cloud.gateway.test.TestEnableWebfluxSecurityAutoConfiguration

0 commit comments

Comments
 (0)