最正确的 OAuth 设计方法是使用范围和声明。这样做可以有效地允许访问令牌和用户身份在微服务之间流动,并提供正确的保护并且没有安全问题。最好通过一个例子来解释。
SCENARIO
考虑在线销售业务场景。客户端与订单服务交互,订单服务调用计费服务。客户端不调用计费服务,但用户启动的操作在那里执行。
访问代币流
OAuth 标准未定义范围的设计方式。通常它们是由架构师设计的,用于端到端的业务流程。此处显示了一个示例,其中每个 API 都会接收并验证每个请求的 JWT 访问令牌。请注意,有时客户端会发送不同的凭证,例如 cookie 或引用令牌,但这些凭证会转换为 JWT 访问令牌,然后传递给 API。
用户身份从 Orders API 流向 Billing API。由于它使用 JWT 格式,因此它仍然是可验证和可审计的。这两个 API 都会以零信任的方式验证每个请求的 JWT。
API 还会检查所需的范围。在此示例中,我使每个微服务的范围相同,因为它们都覆盖相同的业务领域。计费 API 可能只允许此范围用于创建发票操作。如果访问令牌发送到任何其他计费端点或范围不足的任何其他 API,则会立即拒绝并显示 403 禁止响应。为了创建发票,计费 API 可能会添加其他限制,例如与检查有效负载中的订单 ID 相关的限制。
JWT 验证后,API 信任令牌中的声明并将其用于业务授权。这将根据用户身份、角色和其他值锁定用户可以执行的操作。因此,如果用户能够使用浏览器工具提取其 API 凭据并使用 Postman 等工具重播它,他们应该获得与在 UI 会话中获得的 API 完全相同的访问权限。
更高权限的操作
这些 API 也将被其他用户和客户端使用,他们可能需要调用更高权限的操作。接下来考虑几个调用相同 API 的员工应用程序,这些应用程序也可能会暴露在互联网上。这些可能允许更高的权限并需要多重身份验证:
在这里,我也使用了层次范围,例如sales:payments
,这是设计 API 端点访问的一种可能的技术。不过,范围仍然是高级别的,并且只管理入门级安全性。
其他选项
流动代币还有更高级的选项。例如,OAuth 令牌交换 https://datatracker.ietf.org/doc/html/rfc8693可用于在调用上游 API 之前为同一用户获取不同的令牌。最常见的是,这用于为同一用户获取范围缩小的另一个令牌。
可以为上游 API 获取具有完全不同范围的令牌,但这样做在某些情况下可能会削弱安全性。执行此操作的解决方案通常使用客户端凭据流来获取具有以下范围的令牌billing
,然后在不可验证的标头或 URL 路径段中传递用户 ID。因此,令牌可能有权访问太多用户的数据,并且拥有此类令牌的恶意方可能会更改用户 ID。
单独的基础设施解决方案(例如计费 API 需要相互 TLS)也存在一些问题。他们可能会阻止真正的客户端访问该 API。这可能与企业主的愿望背道而驰。在上面的示例中,它将阻止财务应用程序调用 Billing API。
SUMMARY
如果您需要的话,基础设施解决方案可能是最好的短期战术解决方案。不过,作为未来的方向,目标是通过以最佳方式使用范围和声明来使用 OAuth 提供的零信任成分。