OAuth2从资源服务器流向另一个

时间:2017-07-17 14:11:10

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

实施不可知的讨论。

假设下图。 enter image description here

  • 黑线表示哪些服务受auth服务器保护。
  • 绿线显示服务之间的互动(客户和订单服务需要通过将访问数据库的数据服务.StandAlone服务不喜欢其他服务)
  • 红线显示特定的请求流程
  • 数据服务不直接暴露在外部,只能由其他允许的服务访问。

我假设当用户使用auth服务器进行身份验证时,客户端已获得访问令牌。选择哪个流(隐式,授权代码,密码)是无关紧要的。我想从客户端已经获得访问令牌的角度开始讨论。

从那时起,我很清楚当客户端需要访问单个资源服务器时会发生什么。

  1. 向资源服务器发出请求并传递获取的令牌
  2. 资源服务器验证令牌(不相关的方式)
  3. 如果有效,请提供服务请求。
  4. 因此,在该图中,如果客户端要访问" StandAlone Service"(它不与任何其他资源服务器通信),那么流程对我来说很清楚。

    当客户端跟随图中的红线时,我遇到了麻烦。所以我需要访问一个服务(资源服务器),以便回复需要访问另一个服务(也是资源服务器)。在这种情况下流程如何?

    情景1。

    1. "订单服务"既设置为资源服务器又设置为客户端。
    2. 客户使用访问令牌发出请求,但是"订单服务"将使用自己的客户端凭证获取另一个令牌,以便与"数据服务"进行对话。
    3. 我在这里看到的问题是我放弃了用户权限。我将执行对数据服务的请求"使用"订购服务"权限,而不是用户的权限。

      情景2。

      1. "订单服务"仅设置为资源服务器。
      2. 客户使用用户令牌和"订单服务"将同一令牌转发到"数据服务"
      3. 这里我使用用户的权限执行,但现在我看到了我的"数据服务"暴露并对任何其他服务开放。 (实际上我不知道oauth2是否提供了这样的限制。仅限客户端限制到特定的资源服务器)

        情景3。

        在这里,我看到上述场景的组合,其中"订单服务"将为数据服务提供两种令牌。用户访问令牌,以便使用正确的权限和"订单服务"执行请求。客户端访问令牌,以便我知道该服务可以与"数据服务"进行对话。

        实施

        我正在使用spring boot和spring security来设置上面看到的oauth2组件。我已经有一个auth服务器,一个资源服务器和一个客户端。客户端此时与资源服务器进行通信,而不会将请求委托给另一个资源服务器。

        根据最佳方法,我将如何进入实施方面?我需要对资源服务器进行哪些更改才能使它们能够安全地相互通信?

        感谢您的时间

3 个答案:

答案 0 :(得分:2)

根据我的理解,第一种方法似乎是正确的,因为“订单服务”充当“数据服务”资源服务器的客户端。所以它应该使用作为客户端提供的访问令牌。

OIDC专门用于客户端(阅读here。也可以在该页面上查找“为什么使用 - 访问 - 令牌 - 安全 - apis”),没有资源服务器应该使用该id_token进行任何操作(但确实,每个实现者都会就此问题做出自己的决定,因此令人困惑。我建议阅读here)。

因此,从我的观点来看,我们有这些替代方案可以满足您的要求:

  1. “订购服务”充当客户,在“数据服务”资源(或至少您要访问的“资源类型”)下具有完全控制权。如果您需要向“数据服务”提供一些关于谁是“订单服务”的发起人请求任何内容的信息,那么这是请求资源时有效载荷的一部分(它不是access_token的一部分)。
  2. 资源所有者(用户)之前已授予对“数据服务”特定资源的“订单服务”的特定访问权限。与前一点类似,但“订单服务”无法访问所有“数据服务”资源。来自发起人的信息仍然是有效载荷的一部分。
  3. 为了避免将发件人信息作为有效载荷的一部分传递,我想我们需要能够“按需”生成“订单服务”客户端凭证,其中包含与链接到的资源所有者有关的一些字段,或者以前以某种方式创建的用户他们并链接到他的个人资料,以便以后可以通过“订单服务”检索。这就是我的问题开始变得混乱的地方,并且文档不明确(OAuth2 RFC没有涵盖这一点)。
  4. 将整个系统视为一个系统,只有一个客户端。从前端客户端(用户与之交互的客户端)接收的access_token包含所需的所有特定范围。 “客户”,“订购服务”,“客户服务”共享相同的客户端凭证,只是将“访问令牌”从一个转发到另一个(因此它不再是“客户端凭证授权”)。所以他们都拥有完全相同的权限集。资源所有者将在首次登录授权服务器时授予这些权限,因此它并没有那么糟糕。但显然这意味着您无法优化每个“子模块客户端”的权限,资源服务器将无法根据访问令牌userinfo请求确定哪个“子模块”是请求(如果需要,它应该是有效负载的一部分)。这具有安全隐患肯定
  5. 到目前为止,我只使用了备选方案4(用于内部网络)。所以不能多说现实世界中的其他3个。

    我还没有看到基于“社区接受标准”的具体解释,说明如何达到你所要求的(并且这与规范没有直接矛盾)。

答案 1 :(得分:1)

您正在混合授权和身份概念。

oauth2角色(resource ownerresource serverauthorization serverclient)是角色,而不是身份。您的订单服务在一个方案中具有resource server角色,在另一个方案中具有client角色。

方案1是正确的方法。

Oauth2令牌确实与某些资源标识符绑定,因此将客户端限制为特定资源是一种内置功能。<​​/ p>

使用Oauth2 scope概念

处理客户端相关授权集

如果要跨请求流传播最终用户身份,则必须在流中传播身份令牌(例如JWT)(请参阅OIDC)。但是,处理最终用户授权可能不是数据服务的责任。

答案 2 :(得分:0)

我遇到相同的情况(我们称之为服务器到服务器的调用情况),到目前为止,我已经通过将服务A设置为服务B的服务B的oauth2客户端->服务B调用来访问它。

当您将服务A设置为服务B的oauth2客户端时,它与用户原始令牌具有的oauth2范围无关。因为它是服务A调用服务B,所以A应该能够使用A自己的oauth2访问令牌来调用B,该令牌具有A调用服务B所需的所有oauth2范围。

为此,您可以1)只需在A端使用某种配置并在调用服务B时在SecurityContextHolder中交换OAuth2Authentication,并在从服务B获得响应时恢复原始的OAuth2Authentication或2)添加逻辑服务A中,该服务请求具有预配置的oauth2 clientId和机密的访问令牌,并使用它来调用服务B。(需要完成与案例1中提到的相同的交换逻辑。

如果您不将服务A视为服务B的oauth2客户端,而是使用与原始用户令牌相同的oauth2范围,那么您将面临继续授予将要求下游服务调用的任何oauth2范围的问题用户的oauth2访问令牌,并且当进行了多个服务到服务的调用时(或添加/修改了下游调用的oauth2范围时),您将永远无法正确跟踪它。通过将服务A视为服务B的oauth2客户端,您只需注意服务A的oauth2 clientId(或access_token)的授予范围之间即可。