Support ServerExchangeRejectedHandler @Bean

Closes gh-15975
This commit is contained in:
Rob Winch
2024-10-22 18:17:15 -05:00
parent e48d6b039b
commit e86d88d0cf
3 changed files with 62 additions and 1 deletions

View File

@@ -31,6 +31,7 @@ import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.reactive.result.view.CsrfRequestDataValueProcessor;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.WebFilterChainProxy;
import org.springframework.security.web.server.firewall.ServerExchangeRejectedHandler;
import org.springframework.security.web.server.firewall.ServerWebExchangeFirewall;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@@ -67,9 +68,11 @@ class WebFluxSecurityConfiguration {
@Bean(SPRING_SECURITY_WEBFILTERCHAINFILTER_BEAN_NAME)
@Order(WEB_FILTER_CHAIN_FILTER_ORDER)
WebFilterChainProxy springSecurityWebFilterChainFilter(ObjectProvider<ServerWebExchangeFirewall> firewall) {
WebFilterChainProxy springSecurityWebFilterChainFilter(ObjectProvider<ServerWebExchangeFirewall> firewall,
ObjectProvider<ServerExchangeRejectedHandler> rejectedHandler) {
WebFilterChainProxy webFilterChainProxy = new WebFilterChainProxy(getSecurityWebFilterChains());
firewall.ifUnique(webFilterChainProxy::setFirewall);
rejectedHandler.ifUnique(webFilterChainProxy::setExchangeRejectedHandler);
return webFilterChainProxy;
}

View File

@@ -32,6 +32,8 @@ import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.config.users.ReactiveAuthenticationTestConfiguration;
import org.springframework.security.web.server.WebFilterChainProxy;
import org.springframework.security.web.server.firewall.HttpStatusExchangeRejectedHandler;
import org.springframework.security.web.server.firewall.ServerExchangeRejectedHandler;
import org.springframework.security.web.server.firewall.ServerWebExchangeFirewall;
import org.springframework.web.server.handler.DefaultWebFilterChain;
@@ -66,6 +68,18 @@ public class WebFluxSecurityConfigurationTests {
assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
}
@Test
void loadConfigWhenCustomRejectedHandler() throws Exception {
this.spring.register(ServerHttpSecurityConfiguration.class, ReactiveAuthenticationTestConfiguration.class,
WebFluxSecurityConfiguration.class, CustomServerExchangeRejectedHandlerConfig.class).autowire();
WebFilterChainProxy webFilterChainProxy = this.spring.getContext().getBean(WebFilterChainProxy.class);
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/;/").build());
DefaultWebFilterChain chain = emptyChain();
webFilterChainProxy.filter(exchange, chain).block();
assertThat(exchange.getResponse().getStatusCode())
.isEqualTo(CustomServerExchangeRejectedHandlerConfig.EXPECTED_STATUS);
}
@Test
void loadConfigWhenFirewallBeanThenCustomized() throws Exception {
this.spring.register(ServerHttpSecurityConfiguration.class, ReactiveAuthenticationTestConfiguration.class,
@@ -99,6 +113,18 @@ public class WebFluxSecurityConfigurationTests {
}
@Configuration
static class CustomServerExchangeRejectedHandlerConfig {
static HttpStatus EXPECTED_STATUS = HttpStatus.I_AM_A_TEAPOT;
@Bean
ServerExchangeRejectedHandler rejectedHandler() {
return new HttpStatusExchangeRejectedHandler(EXPECTED_STATUS);
}
}
@Configuration
static class SubclassConfig extends WebFluxSecurityConfiguration {