【问题标题】:Using scopes as roles in Spring Security OAuth2 (provider)在 Spring Security OAuth2(提供者)中使用作用域作为角色
【发布时间】:2014-04-20 11:58:06
【问题描述】:

让我们考虑一个相当简单的假设应用程序,用户可以在其中阅读或撰写帖子。

有些用户可以阅读和撰写文章,而有些用户只能阅读它们。使用 Spring Security (3.2.1),我通过两个角色对此进行建模:

  • ROLE_WRITE:此角色授予用户撰写帖子的权限。
  • ROLE_READ:此角色授予用户阅读帖子的权限。

使用 Spring 安全性实现这一点相当简单......

现在我还想通过使用 Spring Security OAuth (version 2.0.0.M3 ATM) 实现 OAuth2 提供程序,允许第三方应用代表用户读取和写入帖子。

在授权步骤中,应用会询问用户是否愿意授予代表他们阅读和/或撰写帖子的权利。这里的用户在这里授予范围(而不是角色)。

然后,当 OAuth2 消费者调用我的 REST API 时,Spring Sec OAuth 会授权授予的令牌并创建一个身份验证,其中包含用户及其所有角色和仅授予的范围。

问题(和问题)是我现在必须编写不同的安全逻辑,具体取决于 API 是由通常经过身份验证的用户调用(只需检查角色)还是通过 OAuth2 调用(检查角色 + 范围) .

是否可以在 Spring Security OAuth2 中“合并”角色和范围的概念,以便在授权步骤期间,用户授予应用程序他们拥有的 角色 的子集(并且拥有OAuth2 身份验证仅在授予的权限中报告这些)?这样当第 3 方应用程序进行 API 调用时,身份验证中的角色是授予的角色吗?这样我就不必编写任何 OAuth2 特定的安全逻辑。

【问题讨论】:

    标签: spring oauth spring-security oauth-2.0 spring-security-oauth2


    【解决方案1】:

    作用域(和角色)是任意字符串,所以如果你想使它们相同也没问题。要使访问规则声明相同,您可以编写一个 ExpressionHandler,根据它找到的 Authentication 的类型,使用相同的值测试权限或范围。

    阅读 cmets 后建议使用不同的方法:添加自定义 TokenStoreResourceServerTokenServices。这些是易于访问的扩展点,并且允许修改 OAuth2Authentication 以便其授予的权限与范围相同。

    然而,我的偏好是使用OAuth2RequestFactory 控制允许的范围,在令牌授予时将它们限制为与用户权限一致的值。

    【讨论】:

    • 谢谢戴夫。我忘了提到我在我的服务方法上使用了@Secured 注释(我没有使用 Spring Sec HTTP 路径安全/antMatchers("/path").access(...))。这种方法还能管用吗?
    • 我不明白为什么不这样做。现在我们处于“你做了什么,为什么没有成功?”的领域
    • 似乎我可以在 GlobalMethodSecurityConfiguration.accessDecisionManager 中用我自己的 impl 替换 RoleVoter。这将处理 @Secured 方法,但我必须小心任何其他直接访问 authentication.getAuthorities() 的代码。在查看了一些代码之后,在我的情况下似乎最简单的方法是实现我自己的 OAuth2AuthenticationManager ,它将返回仅具有授予权限的身份验证。我看到它在 OAuth2ResourceServerConfigurer.oauthAuthenticationManager 中被实例化。有没有容易换成我自己的?
    • 我们还没有将它暴露给 java config builder,但是过滤器上有一个 setter。因此,当我们在 Spring Oauth 中对其进行排序时,您可以自己使用它(而不是使用 @EnableResourceServer)。如果您愿意,请在 GitHub 中提出问题。
    • 最后一条评论:如果我是你,我会选择自定义的TokenStore(或ResourceServerTokenServices),你可以@EnableResourceServer 适配器中自定义它。
    【解决方案2】:

    您可以配置自己的 AccessTokenConverter(主要用于 JWT)并从 JWT 访问令牌中提取您想要的声明并生成一个授权对象。只需定义一个返回 AccessTokenConverter 的 Bean 工厂

    【讨论】:

      猜你喜欢
      • 2020-12-31
      • 2016-11-09
      • 2015-07-29
      • 1970-01-01
      • 2016-09-05
      • 1970-01-01
      • 2021-05-17
      • 1970-01-01
      • 2020-10-20
      相关资源
      最近更新 更多