I need to add security into a Webflux based app and have requirements that mean I need to add multiple filter chains. However, the current implementation of WebFilterChainProxy
uses Flux.filterWhen(...)
which, if I'm reading the docs correctly, will only ever return the first match in the chain.
Given the above I have three questions:-
My react knowledge is very limited, can someone confirm if my understanding of what filterWhen
does is correct?
If so, can anyone suggest a way to get multiple filter chains to work in the new Spring Security 5 reactive model?
If I have misunderstood how the filterWhen method works, could any one make any suggestions why only one of my filter chains is processed?
The way I am adding filters to the chain is in multiple configuration methods annotated with @Order
, similar to the code block below.
@Configration
@EnableWebFluxSecurity
public class SecurityConfig
...
@Bean
@Order(1)
SecurityWebFilterChain chain1(ServerHttpSecurity http) {
return http.httpBasic().disable()......
}
@Bean
@Order(2)
SecurityWebFilterChain chain2(ServerHttpSecurity http) {
return http.httpBasic().disable()......
}
@Bean
@Order(3)
SecurityWebFilterChain chain3(ServerHttpSecurity http) {
return http.httpBasic().disable()......
}
...
}
When I debug the application I can see that all three filters have been added to the WebFilterChainProxy
but I only ever get one matched filter back. I need to find a way of returning all filters that match.
Can anyone help please?
Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed from the configuration depending on which services are required. The ordering of the filters is important as there are dependencies between them.
In a web application, we drive Spring security through the servlet filters. Servlet filters works by intercepting the request before it reaches to the actual resource (e.g. Spring controller).
There are three ways to add your filter, Annotate your filter with one of the Spring stereotypes such as @Component. Register a @Bean with Filter type in Spring @Configuration. Register a @Bean with FilterRegistrationBean type in Spring @Configuration.
The best way to debug the Order of your configuration is to place a breakpoint in SpringSecurityFilterChain. java at startup. This will reveal the Order of the Configurers.
I was able to finally resolve this by using ServerWebExchangeMatchers. My use case involved enabling Basic Authentication when accessing Spring Actuator endpoints and no authentication on other paths. I was able to accomplish this by the following code:
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity)
{
httpSecurity
.csrf().disable()
.logout().disable()
.formLogin().disable();
httpSecurity.securityMatcher(ServerWebExchangeMatchers.pathMatchers("/actuator/**"))
.httpBasic()
.and()
.authorizeExchange()
.pathMatchers("/actuator/**")
.hasRole(ACTUATOR_ADMIN_ROLE);
return httpSecurity.build();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With