mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	Support ServerExchangeRejectedHandler @Bean
Closes gh-15975
This commit is contained in:
		
							parent
							
								
									e48d6b039b
								
							
						
					
					
						commit
						e86d88d0cf
					
				| @ -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; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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 { | ||||
| 
 | ||||
|  | ||||
| @ -200,3 +200,35 @@ firewall.setAllowedHeaderValues { | ||||
| } | ||||
| ---- | ||||
| ====== | ||||
| 
 | ||||
| The `ServerExchangeRejectedHandler` interface is used to handle `ServerExchangeRejectedException` throw by Spring Security's `ServerWebExchangeFirewall`. | ||||
| By default `HttpStatusExchangeRejectedHandler` is used to send an HTTP 400 response to clients when a request is rejected. | ||||
| To customize the behavior, users can expose a `ServerExchangeRejectedHandler` Bean. | ||||
| For example, the following will send an HTTP 404 when the request is rejected: | ||||
| 
 | ||||
| 
 | ||||
| .Send 404 on Request Rejected | ||||
| [tabs] | ||||
| ====== | ||||
| Java:: | ||||
| + | ||||
| [source,java,role="primary"] | ||||
| ---- | ||||
| @Bean | ||||
| ServerExchangeRejectedHandler rejectedHandler() { | ||||
| 	return new HttpStatusExchangeRejectedHandler(HttpStatus.NOT_FOUND); | ||||
| } | ||||
| ---- | ||||
| 
 | ||||
| Kotlin:: | ||||
| + | ||||
| [source,kotlin,role="secondary"] | ||||
| ---- | ||||
| @Bean | ||||
| fun rejectedHandler(): ServerExchangeRejectedHandler { | ||||
|     return HttpStatusExchangeRejectedHandler(HttpStatus.NOT_FOUND) | ||||
| } | ||||
| ---- | ||||
| ====== | ||||
| 
 | ||||
| Handling can be completely customized by creating a custom `ServerExchangeRejectedHandler` implementation. | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user