2017-07-17 49 views
5

实施不可知论的讨论。OAuth2从资源服务器流向另一个

假设下图。 enter image description here

  • 黑色线条显示哪些服务受auth服务器保护。
  • 绿线显示了服务之间的交互(客户和订单服务需要经过数据服务,将访问数据库。独立的服务并不像其他服务)
  • 红线显示特定请求流
  • 数据服务不直接暴露于外部,只能由允许这样做的其他服务访问。

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

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

  1. 也求资源服务器,并通过获得的令牌
  2. 资源服务器验证令牌(不相干如何)
  3. 如果有效,服务的要求。

因此,在该图中,如果客户端要访问“StandAlone Service”(不与任何其他资源服务器通信),该流程对我来说很清楚。

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

方案1.

  1. “订单服务”是建立既作为资源服务器和客户端。
  2. 客户端使用访问令牌发出请求,但“订单服务”将获取具有自己的客户端凭证的另一个令牌,以便与“数据服务”交谈。

这里的问题,我看到它是我松散的用户权限。我将使用“订单的服务”权限执行对“数据服务”的请求,而不是用户的权限。

场景2.

  1. “订单服务” 是设置只能作为资源服务器。
  2. 客户端与使用者令牌和“订单服务”请求将向下转发同样的道理,以“数据服务”

在这里,我执行与用户的权限,但现在我看到我的“数据服务“已公开并可用于任何其他服务。 (其实我不知道的oauth2提供这样的限制。限制客户端只对特定资源服务器)

方案3.

在这里,我看到的上述情况组合,其中“订单服务”将向数据服务提供这两个令牌。用户访问令牌,以便使用正确的权限和“Order's service”客户端访问令牌执行请求,以便我知道允许该服务与“数据服务”进行通信。

实施

我使用的弹簧引导和春季安全,以建立我上面看到的oauth2组件。我已经有了一个auth服务器,一个资源服务器和一个客户端。当前的客户端与资源服务器进行通信,而不会将请求委托给其他资源服务器。

根据最佳方法我将如何去实现方面?我需要对资源服务器进行哪些更改,以便他们可以安全地进行对话?

谢谢你的时间

回答

0

你在混合授权和身份概念。

oauth2角色(resource owner,resource server,authorization serverclient)是角色而不是身份。您的订单服务在一个场景中具有resource server角色,在另一个角色中具有client角色。

方案1是正确的方法。

Oauth2令牌确实绑定到一些资源标识符,因此限制客户端到特定资源是一种内置功能。使用的oauth2 scope概念

如果你想传播跨越的请求最终用户的身份流向你要传播身份令牌

客户端的相关授权集的处理(例如JWT一个)跨流动(见OIDC)。但是,处理最终用户授权不是数据服务的责任。

1

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

OIDC专门用于客户端(阅读here。也查看该页面的“why-use-access-tokens-to-secure-apis”),没有资源服务器应该使用该id_token作任何事情(但它是真实的每个执行者都遵循自己的决定,所以它很混乱,我推荐阅读here)。

所以,从我的角度来看,我们有这些选择达到你的要求为:

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

到目前为止,我只使用了替代品4(这是为了内部网络的目的)。所以现在不能多说关于其他3个。

我还没有看到基于'社区接受标准'的具体解释如何达到你所要求的(而且这并没有直接抵触规范)。

相关问题