SOA /微服务:如何处理服务间通信中的授权?


18

前景

我们正在从单一平台过渡到更加面向服务的体系结构。我们正在应用非常基本的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来说是完全透明的),预订服务使服务服务获得预订的默认服务,例如航班,保险或租车

在内部讨论此问题时,会弹出几个选项,但我们不确定哪个选项最好:

  1. BookingsServices通信时,它应该只转发他从API网关收到的原始令牌(表明客户端是ExternalApp)。
    • 启示:我们可能需要将不应该被授予的范围授予ExternalApp。示例:ExternalApp可能需要同时具有“预订”和“服务”范围,而只有“预订”范围才足够
  2. BookingsServices通信时,它转发一个令牌,指示该客户端现在已成为Bookings(而不是ExternalApp),并且添加了一个声明,表明Bookings模仿了原始客户端ExternalApp
    • 通过还包括原始客户端是信息ExternalApp服务业务也可以做逻辑如过滤取决于原调用一些服务(如用于内部应用程序,我们应该返回所有的战斗,外部应用程序只有一些)
  3. 服务不应相互通信(因此我们甚至不应面对这个问题)

预先感谢您的输入。


1
您是如何解决这个问题的?我们处于类似情况。
Varun Mehta,

+1:我对您最终解决问题的方式感兴趣。
Dypso

为了执行第3点-服务不会相互通信,您需要一个复合UI。见particular.net/blog/secret-of-better-ui-composition
stevie_c

Answers:


3

我建议您在微服务之间建立内部通信渠道。

例如使用一些像RabbitMQ的消息代理内部发送/接收发布/订阅微服务之间的消息。

然后,您面对服务的第一个最终用户“在您的示例中为预订服务”将负责验证令牌并授权客户通过与IdentityServer进行通信来执行此特定操作。

然后它将通过Message Broker与Services服务进行通信,在这种情况下,无需再次验证令牌。

我想这个模型会更简单,并为您提供更好的性能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.