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 WebFilterC
I'm answering my own question(s) here in the hope it might help the underdstanding of others.
- My react knowledge is very limited, can someone confirm if my understanding of what filterWhen does is correct?
Yes, my understanding here is correct, Flux.filterWhen(...)
will return only the first item matched.
- If so, can anyone suggest a way to get multiple filter chains to work in the new Spring Security 5 reactive model?
Multiple filter chains 'work' out-of-box in the Reactive parts of Spring Security 5, they just work in a mutually exclusive way, e.g. only a single filter will be applied given the use of Flux.filterWhen(...)
.
- If I have misunderstood how the filterWhen method works, could any one make any suggestions why only one of my filter chains is processed?
See the answer to 2. above.
From a wider perspective, my original requirement was to have multiple chains, where more than one chain would be applied but, given the constraints already outlined, this simply wasn't possible. I had to modify what we were doing so that it worked with the framework rather than against it.
We still required multiple filter chains as security requirements were different for different flows and we ended up using the same ServerWebExchangeMatchers in a similar manner as described in @KRam answer.
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();
}