Spring Cloud Gateway 访问Principal

问题描述 投票:0回答:1

这个问题与我对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(...)
spring-webflux spring-cloud-gateway
1个回答
0
投票

您可以像这样在方法体中访问主体:

@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;
}
© www.soinside.com 2019 - 2024. All rights reserved.