Skip to content

Commit adc66e1

Browse files
committed
Merge branch '6.2.x' into 6.3.x
Support ServerWebExchangeFirewall @bean Closes gh-15991
2 parents 308e408 + 3ba1263 commit adc66e1

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/reactive/WebFluxSecurityConfiguration.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import io.micrometer.observation.ObservationRegistry;
2323

24+
import org.springframework.beans.factory.ObjectProvider;
2425
import org.springframework.beans.factory.annotation.Autowired;
2526
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
2627
import org.springframework.context.ApplicationContext;
@@ -33,6 +34,7 @@
3334
import org.springframework.security.web.server.ObservationWebFilterChainDecorator;
3435
import org.springframework.security.web.server.SecurityWebFilterChain;
3536
import org.springframework.security.web.server.WebFilterChainProxy;
37+
import org.springframework.security.web.server.firewall.ServerWebExchangeFirewall;
3638
import org.springframework.util.ClassUtils;
3739
import org.springframework.util.ObjectUtils;
3840
import org.springframework.web.reactive.result.view.AbstractView;
@@ -79,11 +81,12 @@ void setObservationRegistry(ObservationRegistry observationRegistry) {
7981

8082
@Bean(SPRING_SECURITY_WEBFILTERCHAINFILTER_BEAN_NAME)
8183
@Order(WEB_FILTER_CHAIN_FILTER_ORDER)
82-
WebFilterChainProxy springSecurityWebFilterChainFilter() {
84+
WebFilterChainProxy springSecurityWebFilterChainFilter(ObjectProvider<ServerWebExchangeFirewall> firewall) {
8385
WebFilterChainProxy proxy = new WebFilterChainProxy(getSecurityWebFilterChains());
8486
if (!this.observationRegistry.isNoop()) {
8587
proxy.setFilterChainDecorator(new ObservationWebFilterChainDecorator(this.observationRegistry));
8688
}
89+
firewall.ifUnique(proxy::setFirewall);
8790
return proxy;
8891
}
8992

config/src/test/java/org/springframework/security/config/annotation/web/reactive/WebFluxSecurityConfigurationTests.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,24 @@
1616

1717
package org.springframework.security.config.annotation.web.reactive;
1818

19+
import java.util.Collections;
20+
21+
import org.jetbrains.annotations.NotNull;
1922
import org.junit.jupiter.api.Test;
2023
import org.junit.jupiter.api.extension.ExtendWith;
24+
import reactor.core.publisher.Mono;
2125

26+
import org.springframework.context.annotation.Bean;
2227
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.http.HttpStatus;
29+
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
30+
import org.springframework.mock.web.server.MockServerWebExchange;
2331
import org.springframework.security.config.test.SpringTestContext;
2432
import org.springframework.security.config.test.SpringTestContextExtension;
2533
import org.springframework.security.config.users.ReactiveAuthenticationTestConfiguration;
2634
import org.springframework.security.web.server.WebFilterChainProxy;
35+
import org.springframework.security.web.server.firewall.ServerWebExchangeFirewall;
36+
import org.springframework.web.server.handler.DefaultWebFilterChain;
2737

2838
import static org.assertj.core.api.Assertions.assertThat;
2939

@@ -47,6 +57,32 @@ public void loadConfigWhenReactiveUserDetailsServiceConfiguredThenWebFilterChain
4757
assertThat(webFilterChainProxy).isNotNull();
4858
}
4959

60+
@Test
61+
void loadConfigWhenDefaultThenFirewalled() throws Exception {
62+
this.spring
63+
.register(ServerHttpSecurityConfiguration.class, ReactiveAuthenticationTestConfiguration.class,
64+
WebFluxSecurityConfiguration.class)
65+
.autowire();
66+
WebFilterChainProxy webFilterChainProxy = this.spring.getContext().getBean(WebFilterChainProxy.class);
67+
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/;/").build());
68+
DefaultWebFilterChain chain = emptyChain();
69+
webFilterChainProxy.filter(exchange, chain).block();
70+
assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
71+
}
72+
73+
@Test
74+
void loadConfigWhenFirewallBeanThenCustomized() throws Exception {
75+
this.spring
76+
.register(ServerHttpSecurityConfiguration.class, ReactiveAuthenticationTestConfiguration.class,
77+
WebFluxSecurityConfiguration.class, NoOpFirewallConfig.class)
78+
.autowire();
79+
WebFilterChainProxy webFilterChainProxy = this.spring.getContext().getBean(WebFilterChainProxy.class);
80+
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/;/").build());
81+
DefaultWebFilterChain chain = emptyChain();
82+
webFilterChainProxy.filter(exchange, chain).block();
83+
assertThat(exchange.getResponse().getStatusCode()).isNotEqualTo(HttpStatus.BAD_REQUEST);
84+
}
85+
5086
@Test
5187
public void loadConfigWhenBeanProxyingEnabledAndSubclassThenWebFilterChainProxyExists() {
5288
this.spring
@@ -57,6 +93,20 @@ public void loadConfigWhenBeanProxyingEnabledAndSubclassThenWebFilterChainProxyE
5793
assertThat(webFilterChainProxy).isNotNull();
5894
}
5995

96+
private static @NotNull DefaultWebFilterChain emptyChain() {
97+
return new DefaultWebFilterChain((webExchange) -> Mono.empty(), Collections.emptyList());
98+
}
99+
100+
@Configuration
101+
static class NoOpFirewallConfig {
102+
103+
@Bean
104+
ServerWebExchangeFirewall noOpFirewall() {
105+
return ServerWebExchangeFirewall.INSECURE_NOOP;
106+
}
107+
108+
}
109+
60110
@Configuration
61111
static class SubclassConfig extends WebFluxSecurityConfiguration {
62112

0 commit comments

Comments
 (0)