当前位置: 首页 > 知识库问答 >
问题:

在Spring云网关预筛选器中获取SecurityContextHolder

墨宜人
2023-03-14

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

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

当OP发布时,它不工作,并返回NULL。在stackoverflow问题中,有一些关于创建自定义筛选器的建议。但我没有尝试过,因为我想从自定义筛选器访问身份验证对象。在Spring Cloud Gateway自定义过滤器中没有直接获取身份验证对象的方法吗?

谢谢

共有1个答案

柴寂离
2023-03-14

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

@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;
}
 类似资料:
  • 我正在尝试在Spring Cloud Gateway中启用RequestRateLimiter。我havr配置了其他过滤器,甚至是自定义过滤器,但当我将其添加到我的路由中时: 我得到了这个异常(当然,如果我移除RequestRateLimiter筛选器并只保留StripPrefix条目,一切正常。我已经删除了异常的代码):

  • 类似于Spring Cloud Sleuth-获取当前traceId?但在Spring Cloud Gateway GlobalFilter的背景下 我尝试注入TringingContext并获取当前的TracingContext,但当我获取当前的跟踪上下文时,它返回。 我怀疑这是一个问题,我的过滤器没有指定任何。但是,我尝试了HIGHEST_PRECEDENCE和LOWEST_PRECEDENC

  • 我正在使用spring cloud网关过滤器,希望通过过滤请求,但order不使用注释 我试着交换过滤器的顺序,但不起作用。 我期望输出: 但实际输出:

  • 我使用spring cloud gateway将请求路由到我的下游应用程序,我定义了如下的路由器 路由工作正常,现在我需要添加一个预过滤器,它可以执行一些预条件并获得路由路径。但不知道如何动态更改uri。uri(“http://localhost:8081/test") 下面是我在preFilter中尝试的代码。 因此,我需要根据我的自定义过滤器中的db查找返回,从传入路径/user/test/*

  • Spring Cloud Gateway作为OAuth2ResourceServer,具有以下授权配置: 我有一个全局过滤器,负责在每个有效的身份验证请求中执行一些功能,如下所示: 我仍处于学习阶段。任何可能的线索将不胜感激。

  • 我想添加用户的ID作为自定义声明到我的令牌。 但我无法在过滤器中获取用户id,因为依赖注入在过滤器中不起作用。我尝试使用UserService的构造函数,但在这个服务中,我有一个存储库,它是im@Autowiring,所以在调试模式下,我看到userRepository字段为空。 我的问题是我将如何添加这个自定义声明?也许这是添加这个的另一种方式。 我正在学习本教程(没有“旁白”章节)https: