这个问题与我对webflux缺乏了解有关......
创建全局 Spring Cloud Gateway 过滤器时,例如
public class MyGlobalFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
METHOD BODY
return chain.filter(exchange);
}
exchange.getPrincipal() 方法返回一个 Mono,因此访问(我相信)需要作为调用链的一部分来完成。
如何在方法体中访问主体?
我已经尝试过了
exchange.getPrincipal().map(...).subscribe()
但这不会触发。
我知道我可以通过执行以下操作成功地访问主体作为后操作。
return filter.chain(exchange).then(exchange.getPrincipal()).map(...)
您可以像这样在方法体中访问主体:
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return exchange.getPrincipal()
.flatMap(principal -> {
log.info("Principal {}", principal.getName());
return chain.filter(exchange);
});
}
为了处理从
Mono
方法返回的 getPrincipal
为空的情况,您需要执行以下操作:
Principal
值包装为 Optional
(或 Optional.empty
,如果 Mono
为空),因为从稍后调用的方法 Mono<Void>
返回的 chain.filter
完成时没有任何值。因此,如果我们使用 switchIfEmpty
,即使存在 Principal
的值,它仍然会被调用。@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return exchange.getPrincipal()
.map(Optional::of)
.defaultIfEmpty(Optional.empty())
.flatMap(principal -> principal
.filter(this::isAuthorized)
.map(p -> chain.filter(exchange))
.orElseGet(() -> {
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
return exchange.getResponse().setComplete();
}));
}
private boolean isAuthorized(Principal principal) {
// Just an example
return true;
}