spring-projects / spring-projects/spring-security
AuthenticationWebFilter executes filter chain twice per request
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.6k
- Forks
- 6.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 52
Description
I've noticed this for some time in my application logs and thought I was just misconfiguring Spring Security WebFlux somehow. But upon closer examination, I think there's a bug in AuthenticationWebFilter that causes this behavior:
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return this.requiresAuthenticationMatcher.matches(exchange)
.filter((matchResult) -> matchResult.isMatch())
.flatMap((matchResult) -> this.authenticationConverter.convert(exchange))
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.flatMap((token) -> authenticate(exchange, chain, token))
.onErrorResume(AuthenticationException.class, (ex) -> this.authenticationFailureHandler
.onAuthenticationFailure(new WebFilterExchange(exchange, chain), ex));
}
The .switchIfEmpty() here is actually subscribing to the filter chain on downstream subscription, rather than deferring it until it is needed. Shouldn't that line be more like:
.switchIfEmpy(Mono.defer(() -> chain.filter(exchange).then(Mono.empty()))
And, in fact, the method directly below this one uses Mono.defer() for error cases.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in web/src/main/java/org/springframework/security/web/server/authentication/AuthenticationWebFilter.java around the filter method at the referenced line, then compare it with the method below that uses Mono.defer(). Reproduce the request flow and verify that the downstream WebFilterChain is subscribed only when authentication conversion is empty, so the chain executes once per request.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100