繁体   English   中英

如何使用 spring 安全自定义授权评估 spring 云网关中的 HTTP POST 负载

[英]How can I evaluate the HTTP POST payload in spring cloud gateway using spring security custom authorization

我正在尝试保护我的一些 spring 云网关路由:

  1. 用户必须使用 OAUTH2 进行身份验证才能使用这些路由(如果没有 -> 响应 http 401)
  2. JWT 访问令牌必须在“scp”声明中包含一个特定的值(在我的例子中是“2fa”)(如果不是,请回复 http 403)
  3. JSON 有效载荷包含一个属性“user”,该属性必须与 JWT 访问令牌中的“sub”声明具有相同的值。 (如果没有,请回复 http 403)

阅读文档我发现了如何设置 1. 和 2. 不幸的是,关于如何实现 3. 的信息似乎很少。

我在哪里可以找到一个有效的例子?

这是来自 application.yaml 文件的我的 spring 安全设置:

...
spring:
  profiles: production

  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: ${AUTH_URL}/oidc
          jwk-set-uri: ${AUTH_URL}/oidc/jwks.json
...

我的 SecurityWebFilterChain 的配置:

...
 @Bean
  @Order(Ordered.HIGHEST_PRECEDENCE - 3)
  public SecurityWebFilterChain secondFactorScopeApiHttpSecurity(ServerHttpSecurity http) {
    final ServerWebExchangeMatcher baseScopeEndpointsMatcher = new OrServerWebExchangeMatcher(
        new PathPatternParserServerWebExchangeMatcher("/api/fhir"),
        new PathPatternParserServerWebExchangeMatcher("/api/fhir/List**"),
        new PathPatternParserServerWebExchangeMatcher("/api/fhir/Observation**")
    );

    http.securityMatcher(baseScopeEndpointsMatcher)
        .authorizeExchange(exchanges -> exchanges.anyExchange().hasAuthority("SCOPE_2fa"))
        .oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::jwt);
    return http.build();
  }
...

我希望用户看到 HTTP 403,以防负载“用户”属性与 JWT 中的子声明不匹配。

你想要实现的是资源服务器上的一项简单任务,在我看来,资源访问控制是资源服务器的责任,而不是网关,特别是如果访问决策涉及资源本身。

我只想让网关对 OAuth2 透明:保留请求授权 header 以及响应状态代码不变。

我在该系列教程中有一些示例,这些示例逐步构建为基于角色的高级访问控制。 完成前 3 个步骤需要不到一个小时的时间:

  • 第一次使用spring-boot-starter-oauth2-resource-server演示资源服务器安全配置(到目前为止你在网关上实现的)
  • 第 2 部分展示了如何将JwtAuthenticationToken替换为您选择的公开强类型私有声明的实现。 它还大大减少了 Java conf 与我在 spring-boot 周围创建的薄包装之一。
  • 第三次演示安全 SpEL 定制以编写类似
@GetMapping("/on-behalf-of/{username}")
@PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('greet')")
public String getGreetingFor(@PathVariable("username") String username) {
   ... 
} 

当然,在你的情况下,你会使用像myControllerMethod(@RequestBody MyDto dto, Authentication auth)这样的签名和像#dto.sub eq #auth.name这样的表达式,但你明白了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM