You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud Gateway全局过滤器中如何获取Principal?

Spring Cloud Gateway全局过滤器中获取Principal的正确方式

在WebFlux响应式编程里,Mono/Flux是懒加载的——只有当整个响应式链被Spring框架订阅时,逻辑才会执行。你手动调用subscribe()相当于创建了一个脱离框架管理的独立链,自然不会触发执行。下面是两种场景下的正确实现方式:

1. 请求前置阶段获取(转发前处理)

如果要在转发请求前拿到Principal并做处理,得把获取逻辑整合到返回的响应式链中,用flatMap串联操作:

public class MyGlobalFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return exchange.getPrincipal()
                .map(principal -> {
                    // 这里写你的处理逻辑,比如打印用户信息、存到exchange属性里
                    System.out.println("当前登录用户:" + principal.getName());
                    exchange.getAttributes().put("CURRENT_USER", principal);
                    return exchange;
                })
                // 继续执行后续过滤器和请求转发
                .flatMap(chain::filter);
    }
}

2. 请求后置阶段获取(转发后处理)

这就是你已经试成功的方式,适合在请求完成后处理Principal:

public class MyGlobalFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 先执行请求转发,完成后再处理Principal
        return chain.filter(exchange)
                .then(exchange.getPrincipal())
                .map(principal -> {
                    // 后置逻辑,比如记录请求完成日志
                    System.out.println("请求处理完成,用户:" + principal.getName());
                    return principal;
                })
                // 转换为Mono<Void>符合方法返回值要求
                .then();
    }
}

关键提醒

  • 绝对不要在过滤器里手动调用subscribe(),这会脱离Spring响应式上下文,要么逻辑不执行,要么引发线程安全问题。
  • 如果后续过滤器或路由需要复用Principal,可以把它存到ServerWebExchange的属性中,之后用exchange.getAttribute("CURRENT_USER")就能获取到。

内容的提问来源于stack exchange,提问作者Mr R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 19:19:53