可以在服务之间传递 OAuth 访问令牌吗?

Posted

技术标签:

【中文标题】可以在服务之间传递 OAuth 访问令牌吗?【英文标题】:Is it OK to pass on OAuth Access Token between services? 【发布时间】:2017-02-11 21:16:41 【问题描述】:

在 SSO/OAuth/微服务的上下文中考虑以下场景:

    用户使用 OAuth 的隐式流程成功登录到 Web 应用程序。 Web 应用向 Service AService B 请求一些数据,传递用户的访问令牌以授权这两个请求。 服务 A 还调用 服务 B(传递相同的访问令牌!)以构建对初始 Web 应用请求的响应。

现在,可以将用户的访问令牌从 Service A 传递到 Service B 吗?

或者应该Service A使用“Client Credentials”授权来获取它自己的Access Token来授权调用Service B

更新: 请假设这两个服务都属于同一个组织并且都信任同一个授权服务器。此外,这两个服务都位于验证访问令牌的同一个 API 网关后面。

【问题讨论】:

【参考方案1】:

这取决于谁在控制 Web 应用程序,服务 A 和服务 B。如果它们都由同一方运行,则传递令牌没有问题,因为它位于同一个安全域内。

但是如果例如服务 B 由第 3 方运行,然后事情变得有问题,因为服务 B 的管理员可以获取访问令牌并调用服务 A,就好像它是您的 Web 应用程序一样,可能会访问它不应该访问的资源。

您还会注意到,如果服务 A 和服务 B 由 2 个不同的方拥有,除了您之外,您的 Web 应用程序还应该分别获得两个不同的访问令牌来调用服务 A 和服务 B,以防止出现相同的安全问题.

所以答案确实是:这取决于谁在控制什么,即令牌是否跨越管理/安全域。

【讨论】:

所以你是说只要 Web App 和两个服务都由同一个组织控制/拥有就可以了吗?您是否知道任何涵盖此类情况的文档(RFC、OAuth 指南等)?我问的原因是我同意你的回答,我正在寻找额外的“弹药”与我公司内的 SSO 团队讨论这个问题。 这更像是一个通用的安全考虑:访问令牌不应泄露到客户端/RS/AS 之外,请参阅:tools.ietf.org/html/rfc6819#section-4.6.1 实际上在 OAuth 隐式流访问令牌的情况下必须走出 RS/AS 边界。在授权代码流或客户端凭据流的情况下,确实令牌不应泄漏到 RS/AS 边界之外。 令牌总是以任何授权类型发送给客户端,因此它们总是离开 RS/AS;关键是它们不会泄露给与预期不同的客户端/RS 好点。当我说授权码流令牌不会离开客户端/RS/AS 边界时,我实际上想到了用户代理。【参考方案2】:

我看到的方式是,如果您有 2 个不同的服务信任相同的 IDP(STS),那么您可以让服务 A 请求令牌,然后您可以将相同的令牌传递给服务 B 并让服务 B 验证令牌再次。可以传递令牌,因为您不希望用户再次登录以进行另一个服务调用。

另外,这取决于您设置服务的方式。如果服务 A 需要来自服务 B 的一些数据来向用户提供数据,那么我们应该传递相同的用户令牌。我不认为服务应该有他们的访问令牌。

使用用户令牌确实有助于识别每个服务级别的声明和数据访问。因此,最好在将数据发送给用户之前传递用户令牌并让每个服务验证令牌。

【讨论】:

实际上 OAuth 2.0 定义了“Client Credentials”授权类型,所以一般来说服务 A 调用其他服务 B 可以使用此授权类型来获取自己的访问令牌。我的问题是关于服务 A 已经拥有用户的访问令牌的特定情况,从技术上讲,服务 A 可以重用该访问令牌来调用服务 B。问题是这样做是否正确。 是的,可以将服务令牌传递给其他服务,因为您不希望任何服务对公众开放。假设来自服务 A 的响应需要来自服务 B 的一些数据,那么用户不需要知道这一点。同样在服务 B 既可以独立调用也可以从服务 A 调用的场景中,无论谁调用该服务来获取数据令牌,都必须提供。如果从 A 调用,它将传递它已经拥有的令牌,当用户调用它时,他将传递令牌。【参考方案3】:

我找到了以下 3 个选项:

如果每个微服务都在验证令牌,那么我们可以传递相同的令牌。但问题是 - 在同一令牌之间可能会过期。

如果我们使用 client_credentials 授权,那么我们有两个问题:一个是,我们需要在下一个微服务中发送用户名/ID。另一个是,我们需要请求两次——第一次是获取访问令牌,第二次是实际调用。

如果我们只在 API 网关(不在微服务中)进行令牌验证,那么我们需要从 API 网关在每个微服务中发送用户名。并且需要更改微服务实现以接受该参数/标头。

【讨论】:

以上是关于可以在服务之间传递 OAuth 访问令牌吗?的主要内容,如果未能解决你的问题,请参考以下文章

JWT 访问令牌:矛盾?

我可以使用 Android Account Manager 获取 App Engine 的 OAuth 访问令牌吗?

您可以让 Google OAuth 2.0 访问令牌持续更长时间吗?

Facebook Oauth 2.0 访问令牌会过期吗?

Spring oauth2 验证令牌请求

oauth2.0如何传递访问令牌