Describe the bug
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange).onErrorResume(AccessDeniedException.class, (denied) -> exchange.getPrincipal()
.filter((principal) -> (!(principal instanceof Authentication) || (principal instanceof Authentication
&& !(this.authenticationTrustResolver.isAnonymous((Authentication) principal)))))
.switchIfEmpty(commenceAuthentication(exchange,
new InsufficientAuthenticationException(
"Full authentication is required to access this resource")))
.flatMap((principal) -> this.accessDeniedHandler.handle(exchange, denied)).then());
}
switchIfEmpty always call commenceAuthentication even if the return value of filter is non empty Mono.
To Reproduce
Steps to reproduce the behavior.
Expected behavior
I'm a new in Reactor, I wanna know whether it's suitable to use Mono.defer() here.
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange).onErrorResume(AccessDeniedException.class, (denied) -> exchange.getPrincipal()
.filter((principal) -> (!(principal instanceof Authentication) || (principal instanceof Authentication
&& !(this.authenticationTrustResolver.isAnonymous((Authentication) principal)))))
.switchIfEmpty(Mono.defer(() -> commenceAuthentication(exchange,
new InsufficientAuthenticationException(
"Full authentication is required to access this resource"))))
.flatMap((principal) -> this.accessDeniedHandler.handle(exchange, denied)).then());
}
Sample
A link to a GitHub repository with a minimal, reproducible sample.
Reports that include a sample will take priority over reports that do not. At times, we may require a sample, so it is good to try and include a sample up front.
Comment From: ccwxl
I also encountered the same problem. How did you solve it?
Comment From: ccwxl
why close?
Comment From: YazidLee
why close?
I went through several implementations in the Spring security library, for example:
org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint
Their commence methods are all wrapped with a deferred Mono by using Mono.defer or Mono.fromRunnable, like:
public class HttpBasicServerAuthenticationEntryPoint implements ServerAuthenticationEntryPoint {
// ...
@Override
public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException ex) {
return Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().set(WWW_AUTHENTICATE, this.headerValue);
});
}
// ...
}