前景
我们正在从单一平台过渡到更加面向服务的体系结构。我们正在应用非常基本的DDD原则,并将我们的域划分为不同的有界上下文。每个域都是分布式的,并通过Web API(REST)公开服务。
由于我们的业务性质,我们提供诸如订舱,服务,客户,产品等服务。
我们还建立了一个Identity Server(基于Thinktecture Identity Server 3),其主要作用是:
- 集中身份验证(给定颁发令牌的凭据)
- 在令牌中添加声明,例如:客户范围(按照客户,我是指执行请求的应用程序),客户标识符(按照客户,我是指使用该应用程序的人)
我们还介绍了API网关的作用,它可以集中外部访问我们的服务。API网关提供的功能不需要深入了解内部域,例如:
- 反向代理:将传入请求路由到适当的内部服务
- 版本控制:API网关的一个版本映射到内部服务的不同版本
- 身份验证:客户端请求包括由Identity Server发行的令牌,API网关会验证令牌(确保用户说的是她的身份)
- 节流:每个客户端的请求数量限制
授权书
与授权有关,这不是在API网关中管理,而是在内部服务本身中进行管理。我们目前正在执行两种主要的授权类型:
- 基于客户范围的授权。示例:客户端(使用我们的API的外部应用程序)需要范围“ bookings”来访问Bookings服务API端点
- 基于客户的授权。示例:仅当客户(使用应用程序的自然人)是预订的参与者时,才能从预订服务访问端点GET / bookings
为了能够处理内部服务中的授权,API网关仅转发令牌(在将请求路由到内部服务时),该令牌既包含有关客户端(执行请求的应用程序)的信息,也包含有关客户的信息(作为声明)有人在客户端应用程序中登录的情况)。
问题描述
到目前为止,到目前为止还不错,直到我们引入了服务间通信(某些服务可以与其他服务进行通信以获得一些数据)。
题
在服务间通信中,我们应该如何处理授权?
考虑的选项
为了讨论不同的选项,我将使用以下示例方案:
- 我们有一个名为ExternalApp的外部应用程序,该应用程序访问我们的API(可以将ExternalApp视为客户端),以建立预订流程
- ExternalApp需要访问预订服务,因此我们授予ExternalApp范围“预订”
- 在内部(这对于ExternalApp来说是完全透明的),预订服务使服务服务获得预订的默认服务,例如航班,保险或租车
在内部讨论此问题时,会弹出几个选项,但我们不确定哪个选项最好:
- 当Bookings与Services通信时,它应该只转发他从API网关收到的原始令牌(表明客户端是ExternalApp)。
- 启示:我们可能需要将不应该被授予的范围授予ExternalApp。示例:ExternalApp可能需要同时具有“预订”和“服务”范围,而只有“预订”范围才足够
- 当Bookings与Services通信时,它转发一个令牌,指示该客户端现在已成为Bookings(而不是ExternalApp),并且添加了一个声明,表明Bookings模仿了原始客户端ExternalApp
- 通过还包括原始客户端是信息ExternalApp的服务业务也可以做逻辑如过滤取决于原调用一些服务(如用于内部应用程序,我们应该返回所有的战斗,外部应用程序只有一些)
- 服务不应相互通信(因此我们甚至不应面对这个问题)
预先感谢您的输入。