我有以下REST服务:
- 一个向外界公开的 * 聚合器 * 服务。它由用户OAuth 2.0访问令牌保护。这个 Aggregator 调用 Internal 服务。
- Internal 服务位于网络级别**,不**暴露于外部世界。它也由相同的用户OAuth 2.0访问令牌保护。访问令牌从 Aggregator 传递到 Internal 服务。
现在让我们假设 * 内部 * 服务意外地暴露给外部世界。从理论上讲,用户可以对 Internal 服务进行不应该允许的更改。
是否有一种方法可以额外保护 Internal 服务,使用户无法访问它,即使它会意外暴露给他们?
同时使用机器对机器(M2M)令牌和用户令牌来保护 * 内部 * 服务是否可能或明智?
1条答案
按热度按时间cnh2zyt31#
最正确的OAuth设计方法是使用范围和声明。这样做有效地允许访问令牌和用户身份在微服务之间流动,具有正确的保护并且没有安全问题。最好用一个例子来解释。
酒店SCENARIO
考虑一个在线销售业务场景。客户端与订单服务交互,订单服务调用计费服务。客户端不调用计费服务,但是在那里执行用户发起的操作。
访问令牌流
OAuth标准没有定义作用域的设计方式。它们通常由架构师设计,用于端到端的业务流。这里显示了一个示例,其中每个API接收并验证每个请求的JWT访问令牌。请注意,有时客户端会发送不同的凭证,例如cookie或引用令牌,但这些凭证会被转换为JWT访问令牌,并将其交付给API。
用户身份从Orders API流向Billing API。它仍然是可验证和可审计的,因为它使用JWT格式。这两个API都以零信任的方式对每个请求验证JWT。
API还检查所需的作用域。在这个例子中,我为每个微服务设置了相同的范围,因为它们都覆盖相同的业务领域。Billing API可能只允许此范围用于创建发票操作。如果访问令牌被发送到任何其他Billing端点或任何其他API,其中范围是不够的,它会立即被拒绝,并返回403 forbidden响应。要创建发票,Billing API可能会添加其他限制,例如与有效负载中订单ID的检查相关。
在JWT验证之后,API信任令牌中的声明并将其用于业务授权。这将根据用户身份、角色和其他值锁定用户可以执行的操作。因此,如果用户能够使用浏览器工具提取他们的API凭据,并使用Postman等工具重播它,他们应该获得与他们在UI会话中获得的API完全相同的访问权限。
高级特权业务
这些API也将被其他用户和客户端使用,他们可能需要调用更高权限的操作。接下来考虑几个调用相同API的员工应用程序,它们也可能暴露在互联网上。这些可能允许更高的权限,并需要多因素身份验证:
在这里,我还使用了分层作用域,比如
sales:payments
,这是一种设计对API端点的访问的可能技术。但是作用域仍然是高级别的,并且只管理入门级安全性。其他选项
有更高级的选项用于流动令牌。例如,OAuth token exchange可用于在调用上游API之前为同一用户获取不同的令牌。最常见的是,这用于为同一用户获取另一个令牌,但范围缩小。
可以为上游API获取具有完全不同作用域的令牌,但这样做在某些情况下可能会削弱安全性。这样做的解决方案通常使用客户端凭证流来获取具有
billing
等作用域的令牌,然后在无法验证的头或URL路径段中传递用户ID。因此,令牌可以访问太多用户的数据,并且具有这样的令牌的恶意方可以改变用户ID。单独的基础设施解决方案,例如要求Billing API的双向TLS,也有一些问题。它们可能会阻止真正的客户端访问该API。这可能会违背企业主的意愿。在上面的示例中,它将阻止财务应用调用Billing API。
摘要
如果您需要的话,基础设施解决方案可能是最好的短期战术解决方案。作为未来的发展方向,目标是通过以最佳方式使用范围和声明来使用OAuth提供的零信任成分。