使用 Spring OAuth 支持多个资源 ID

Posted

技术标签:

【中文标题】使用 Spring OAuth 支持多个资源 ID【英文标题】:Support multiple resource IDs with Spring OAuth 【发布时间】:2019-11-27 20:35:23 【问题描述】:

情况。我们正在使用 Spring OAuth 来验证安全令牌 (JWT)。该令牌具有特定资源 ID 的 aud 声明。以下代码正确验证使用包含客户端 ID resourceId-123 的 aud 声明签名的任何 JWT 令牌:

class ResourceServerConfig 

  @Bean
  protected ResourceServerConfiguration adminResources2() 
    ResourceServerConfiguration resource = new ResourceServerConfiguration() 
      void setConfigurers(List<ResourceServerConfigurer> configurers) 
        super.setConfigurers(configurers)
      
    
    resource.setConfigurers(Collections.<ResourceServerConfigurer>singletonList(new ResourceServerConfigurerAdapter() 
      @Override
      void configure(ResourceServerSecurityConfigurer resources) throws Exception 
        resources.resourceId("resourceId-123")
      

      @Override
      void configure(HttpSecurity http) throws Exception 
        http.antMatcher("/path")
                .authorizeRequests()
                .anyRequest().authenticated()
      
    ))

    resource.setOrder(3)
    return resource
  

问题。我们如何支持同一路径的多个客户端 ID(在上面的示例中,/path)?我已经看到了如何为 不同 API 路径配置具有不同客户端 ID 的多个 Bean 的示例,但我想用 2 个以上的客户端 ID 来保护这个资源。关于如何做到这一点的任何示例或文档?还是我们试图做一些根本不正确的事情?

【问题讨论】:

我可以知道为什么您需要多个客户端应用程序吗?来自不同租户的用户会使用您的 Web 应用吗? @JackJia 暂时只需要支持单租户用户即可。 这听起来很奇怪。一个 API 不应有多个客户端 ID。 谢谢@juunas - 您知道这是 Microsoft 特有的身份验证方式,还是 OAuth 标准? 你检查过过滤器/拦截器吗? 【参考方案1】:

我认为你的做法是错误的。

客户端 ID 与 Spring Security 中的受众不同,而是允许一个客户端使用一个或多个资源 ID,并且 JWT 可能包含多个受众。

所以我认为您应该按照示例,其中不同路径具有不同的资源 ID,为共享路径创建一个新的资源 ID,并将其添加到允许访问它的所有客户端。

例子:

路径:

|----------------+-------------|
| Path           | Resource ID |
|----------------+-------------|
| /client1/info  | client1     |
| /client2/info  | client2     |
| /shared/status | all-clients |
|----------------+-------------|

客户:

|---------+----------------------|
| Client  | Resource IDs         |
|---------+----------------------|
| client1 | client1, all-clients |
| client2 | client2, all-clients |
|---------+----------------------|

如果你能提供一个我可以修改的可运行示例,展示一些东西会更容易,但由于你发布的代码数量有限,这是我能做的最好的。

另一种解决方法是使用不同的范围而不是不同的受众。这将消除对多个资源服务器配置的需求,您可以在.access()@PreAuthorize 中使用#oauth2.hasScope('admin') 之类的表达式。

【讨论】:

以上是关于使用 Spring OAuth 支持多个资源 ID的主要内容,如果未能解决你的问题,请参考以下文章

Spring security OAuth中的多个资源服务器配置

Spring OAuth - 重新加载资源ID和身份验证权限

如何在 Spring Boot oauth2 资源服务器中使用自定义身份验证标头

spring 的 oauth 支持是不是可以用于跨平台提供单点登录与多个 oauth 提供者?

Spring Boot 2 和 OAuth2 客户端凭据不受支持的授权类型

使用 Spring Boot 在单个浏览器会话中使用多个 OAuth2 客户端