I have the following WebFilter
implementation:
@Component
@RequiredArgsConstructor
public class AccountTokenFilter implements WebFilter {
private final TokenService tokenService;
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Mono<Authentication> authMono = tokenService.verifyToken(exchange.getRequest())
.map(AccountTokenAuthentication::new);
return authMono.hasElement().flatMap(authenticated -> {
if (authenticated) {
return authMono.flatMap(auth -> chain.filter(exchange)
.contextWrite(context -> ReactiveSecurityContextHolder.withAuthentication(auth)));
} else {
return chain.filter(exchange);
}
});
}
}
The idea is that it does the following:
- Try to verify the request's authentication token and return the account it's linked to.
- If the account exists, add it to the security context.
- Continue the filter chain with
chain.filter(exchange)
The problem is that somehow, the initial authMono
is getting executed 4 times for each request! Ideally this should be executed only once, but I'm at a loss for how I can even begin to debug this.
If it may help, here is my filter chain configuration:
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.csrf().disable()
.cors().and()
.httpBasic().disable()
.formLogin().disable()
.logout().disable()
.authorizeExchange(spec -> spec
.pathMatchers(HttpMethod.POST, "/accounts", "/tokens").permitAll()
.pathMatchers(HttpMethod.GET, "/tokens/verify").permitAll()
.anyExchange().authenticated()
)
.addFilterAt(accountTokenFilter, SecurityWebFiltersOrder.AUTHENTICATION);
return http.build();
}