微服务之间如何安全通信

4
我希望在不暴露我的API的情况下,实现不同微服务之间的通信。但我遇到了麻烦:微服务使用JWT令牌进行保护,我无法找到一种方法从第一个微服务安全地调用另一个微服务。是否有一种方法可以直接与服务方法通信呢?或者我必须通过API网关发送每个请求,并通过API网关进行安全通信。

为什么不直接将令牌传递给其他微服务呢?每个微服务都可以再次根据相同的令牌进行验证,您只需要在初始API调用中提交它即可。 - T A
我的问题是为什么您需要首先进行跨服务通信?如果纯粹是为了将数据返回给调用者,那么网关API就是最好的选择。个人认为,微服务不应直接相互通信,尽管它们可能关心彼此触发的事件。 - Nope
我的需求是从角色微服务中获取特定角色并将其分配给用户微服务,但是每当我使用Feign或RestTemplate进行内部调用时,其他微服务会抛出401错误。因此,我的要求是实现我的微服务,使得所有通信都可以在微服务之间完成,并且外部通信可以通过API网关完成。 - Akash Prakash
在这里也有讨论:https://security.stackexchange.com/questions/146154/securing-micro-services-architecture-internally - Janos Vinceller
2个回答

6
这完全取决于您的项目的确切需求。
网关API通常用于隐藏微服务的复杂性,对于通常只有一个端点进行交互的外部用户而言,这非常有用。
此外,网关可以处理安全性并验证用户身份(确实有许多公司这样做)。
现在,当您通过网关并且您经过身份验证的请求到达客户端时,通常您已经在请求上拥有用户标识(由网关放置在请求上的)。
因此,您知道用户“John Smith”触发了该请求。
如果您现在需要调用另一个微服务,那么您应该决定(再次是您的决定):
1. 是否需要在那里进行身份验证(也许内部通信之间不必在微服务之间进行保护)。 2. 如果您确实需要在微服务之间进行身份验证,是谁验证请求? 如果是网关,则所有身份验证逻辑都在那里,但每个请求可能需要进行额外的跳转,这可能会很费钱。 或者,如果是直接调用,则每个微服务必须实现身份验证逻辑。当然,有类似 Spring Security 等的解决方案,其他语言/生态系统也有类似的解决方案,但总的来说,这可能很难实现。 3. 如果您从微服务 A 到微服务 B 进行身份验证调用,并且该流程由触发对服务 A 的请求的用户 John Smith 发起,那么您应该决定调用的语义是: - 用户“John Smith”联系了服务 B,还是... - 代表用户 John Smith,服务 A 联系服务 B。 对于具有任何类型的权限系统的授权来说,这一点非常重要。 4. 在技术实现方面,通常可以向请求添加所需令牌的 JWT 标头。如果请求已经过身份验证并且您需要生成用户标识,则可以在请求上仅放置几个标头。

谢谢您的建议。但是让我困扰的是,如果我正在使用API网关对我们的微服务进行身份验证,如何在没有身份验证的情况下进行内部通信。 - Akash Prakash
当微服务A联系微服务B时,它不一定通过网关传递请求。它可以直接联系它...在这种情况下,如果服务B本身没有进行身份验证检查,它将不使用任何身份验证。 - Mark Bramnik
这样做是否会暴露我的API,因为我没有进行认证。能否解释一下我应该建立什么样的基础设施来支持所有这些功能。我正在考虑以下方案:1:创建Zuul API网关,负责所有身份验证、日志记录、跟踪等功能;2:配置服务器用于应用程序相关配置。如果我采用这种方法,我的微服务是否仍然会保持开放状态,任何人都可以直接调用我的微服务API而不需要经过API网关,如何让我的微服务只暴露给API网关和其他微服务。 - Akash Prakash
不确定我是否理解正确。如果您使用“1”,那么所有授权都在网关中完成。一旦您通过网关(用户的初始请求),所有运行在API后面的微服务的后续请求都不需要它们之间的身份验证。当然,它们不会向最终用户“公开”,只有网关会。您应该设置网络基础结构,使得只有网关会暴露给“外部世界”。 - Mark Bramnik
我正在考虑使用服务网格(Kiali)来处理所有的服务间通信,但是我找不到任何相关的项目或代码。如果可能的话,您可以提供一个示例微服务项目,它可以解决我所有的问题,并且是按照企业级应用程序构建的。 - Akash Prakash
这要看情况 - 你可以使用Spring Boot + Spring Security来实现安全性。对于网关,你可以选择Java解决方案,如Zuul或Reactor,或者使用像nginx这样的工具。如果你的环境是异构的(包括Python、Node、Java微服务等),那么Service Mesh就会发挥作用。因此,有很多选择。 - Mark Bramnik

0

你可以有两个API网关:

  • 一个暴露在外面
  • 另一个用于容器内微服务通信。

暴露在外部的那个网关会验证令牌并将声明发送到微服务,这些声明用于路由保护的验证。

在微服务通信之间,使用第二个网关已经拥有的声明进行发送。希望这可以帮助你。如果你发现了任何其他替代方法,请告诉我们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接