首页 > 解决方案 > 在 Spring Cloud Gateway 预过滤器中获取 SecurityContextHolder

问题描述

我在 Spring Boot 项目(版本 2.2.6)中使用 Spring Cloud Gateway 和 Spring Security。我有一个自定义的 Pre 过滤器,它需要在将请求转发到下游服务之前向请求添加标头。Pre 过滤器需要读取 Spring Security 的 Authentication 对象以获取权限,然后才能添加标头(它需要根据权限进行一些查找)。由于 Spring Cloud Gateway 是反应式的,我不能使用静态 SecurityContextHolder 类。引用这个 Stackoverflow 问题ReactiveSecurityContextHolder.getContext() is empty but @AuthenticationPrincipal works,我在我的自定义 Pre 过滤器中尝试了以下内容:

ReactiveSecurityContextHolder.getContext().map(ctx -> ctx.getAuthentication()).block()

正如 OP 发布的那样,它不起作用并返回 null。有一些关于在那个 stackoverflow 问题中创建自定义过滤器的建议。但我没有尝试过,因为我想从自定义过滤器访问 Authentication 对象。Spring Cloud Gateway自定义过滤器中是否没有直接获取Authentication对象的方法?

谢谢

标签: spring-bootspring-securityspring-cloud-gateway

解决方案


下面的代码片段是一个简单的过滤器示例,它提供对身份验证上下文的访问:

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    Mono<Void> monoFilter = ReactiveSecurityContextHolder.getContext().map(sc -> sc.getAuthentication())
            .flatMap(authentication -> {

                // here you can access to Authentication object
                // and implement the pre-filter logic

                return chain.filter(exchange);

            });

    return monoFilter;
}

推荐阅读