微服务通信安全

时间:2020-04-06 11:27:49

标签: .net security jwt microservices

我现在在家做的只是一个宠物项目,因为我大部分时间都将自己锁在室内。话虽如此,但我主要是想将其与所有的钟声放在一起,以便我可以学习一些新知识。我早在2015年就实施了该版本的第1版,并且在我的raspberryPi上像冠军一样运行了5年多了。

对于更新版本(Angular 9 / .net core 3.1),我正在考虑使用Auth0作为我的身份验证提供程序(但是我也正在考虑使用AWS Cognito)。我已经确定了该应用程序的微服务边界,并且将尽可能使用RabbitMQ进行服务间消息传递。但是,在许多情况下,一个MS需要从另一个MS获取数据来完成请求。本质上,某些东西本来就是数据库联接。我在周末对此进行了一些阅读,发现您可以在前端,API网关中进行连接,或者通过让MS A对MS B执行REST查询来进行连接。第一种感觉有点傻,因为然后浏览器必须执行多个请求,第二个将要求我构建一个网关(我只是计划使用NGINX作为反向代理)。因此,我选择了第三个选项...从MS A到MS B的REST请求。

我的问题...

在进行服务间通信时,您如何处理安全性?我考虑过的一些选项,以方便程度进行考虑:

  1. 发出请求时,将Auth标头从MS A转发到MS B
  2. 托管一个MS B的内部实例,该实例不会通过反向代理暴露给互联网,而仅暴露跨微服务通信中所需的功能。 (不确定这种解释是否有意义)
  3. 让MS A向身份验证提供者请求自己的令牌(Auth0,AWS Cognito等),然后使用该令牌呼叫MS B。

是否有标准的方法?

1 个答案:

答案 0 :(得分:1)

这些是要问的好问题,但是不幸的是,没有做到这一点的“标准”方法。我想说您的选择介于1和2之间,每种选择的原因如下:

选项1-发出请求时,将Auth标头从MS A转发到MS B

如果要在拥有不同服务的多个不同团队中大规模应用此实践,那将是最佳途径。 MS B的创建者不一定知道谁在长期向他们打电话,因此,为了确保他们不会带来安全风险,公开其服务的最简单方法是要求可验证的JWT。这样可以防止某人意外地不当地使用其服务。

选项2-托管MS B的内部实例,该实例未通过反向代理向Internet公开,而仅公开了跨微服务通信所需的功能。

您可以想到这种方法,类似于网关上的TLS终止。您可以在每个服务中终止TLS(如JWT的选项1),也可以在网关处终止TLS,以确保来自外界的流量在进入之前被加密,同时允许其在墙壁内自由流动。网关还可以是唯一的负责验证和解码JWT的责任方,然后在检查通过后允许流量在内部自由流动。

此选项对于由单个团队或开发人员维护的应用程序非常实用,因为它很容易编排。如果每个“内部”服务仅对用户ID /主题做出响应,以完成请求并信任,该用户ID是从经过验证的JWT中提取的,则可以更轻松地构建其他内部系统。该解决方案最容易上手,但是如果您不能信任应用或团队中的其他服务或开发人员,则可能会很棘手。

选项3-让MS A向身份验证提供者请求自己的令牌(Auth0,AWS Cognito等),并使用该令牌呼叫MS B

我不建议为每个服务都分配自己的oauth令牌。来自oAuth提供者(如Auth0)的JWT会发布给用户,而不是计算机。

话虽这么说,对云安全性的重要补充是将所有服务之间的流量凭证和白名单列入白名单。这可能是由Kubernetes NetworkPolicys之类的工具强制执行的Cilium之类的事情,或者它们可能是唯一的SSL证书,旨在为堆栈中服务之间的每种关系唯一地代理通信。这种增加的安全性实际上与上面的问题没有任何关系,但是在考虑保护云环境中的进程间通信时,这是一些额外的思考。