微服务方法之间的身份验证

Posted

技术标签:

【中文标题】微服务方法之间的身份验证【英文标题】:Authentication between microservice approach 【发布时间】:2018-01-18 21:11:44 【问题描述】:

我目前正在构建一个基于微服务架构的 API。

我正在使用 JWT 对用户进行身份验证。我了解当用户发送登录请求时,会返回包含用户身份及其角色/权限等的 JWT。然后将此令牌与用户后续请求一起发送,以告诉服务器谁正在发送请求。我认为这是正确的理解。

在正常的单体架构中,这可以很好地工作,正如所解释的那样。如何将其转移到微服务架构以在微服务之间建立信任。

我可以简单地将用户 JWT 转发到下游微服务,但这不允许下游微服务知道谁/哪个上游微服务正在发送请求。

一个例子是我有一个位置微服务。我想允许餐厅微服务调用位置微服务。但我也有一个产品微服务,我不想调用位置微服务。

显然我不能编写产品微服务来调用位置微服务,但这并不能阻止其他人这样做。

有什么建议吗?

【问题讨论】:

似乎与***.com/questions/31044380/…重复 产品服务不允许与定位服务通信还有其他情况吗? 您找到了答案还是仍在寻找答案? @xargs-mkdir 我使用 kubernetes 作为我的容器编排系统。 Kubernetes 允许分离命名空间和部署。因此,对于上面的示例,我不允许 products 命名空间与 location 命名空间对话。此外,对于个人用户验证,我将用户 JWT 转发到任何需要特定帐户权限的微服务。 这可能是您的解决方案dev.to/s2agrahari/… 【参考方案1】:

您至少可以通过以下两种方法使微服务之间的通信安全:

    JWt 令牌:假设微服务 A 想要与微服务 B 通信,那么 A 颁发的令牌和令牌的受众是 B。在这种情况下,令牌由微服务 A 使用其私钥签名。 JWT 中的 aud 字段将代表受众,它可以是单个服务或一组服务。 aud 参数的值应该是服务之间预先约定的值。在微服务中,您可以使用正则表达式来验证受众。例如 aud 可以是 *.samplemicroservice.com。受众服务 B 可以通过检查 aud 字段来检查令牌是否用于它。一旦确认,它可以使用发行者的公钥来验证它。

    相互 SSL:实现它的直接方法是在服务之间使用相互 SSL。每个服务都应该启用 SSL,并且应该将其证书提供给其他服务,并且其他服务应该使用信任库检查证书的有效性。这应该在微服务 A 和微服务 B 上进行验证,以达成相互协议。自签名证书可用作所有服务证书的根 CA,并可通过信任库访问。

这些机制可以有很多变体。特别是在 JWT 令牌的情况下。例如,您可以将令牌颁发责任委托给一个服务,并可以使用颁发者服务的公钥在每个服务中验证令牌。

【讨论】:

【参考方案2】:

这里有两个不同的问题要解决!

1) 用户认证/授权:

您的下游服务服务应将用户 JWT 令牌传递给上游服务(下游取决于上游,下游更靠近前端)。这样所有服务都可以验证 JWT 令牌,我们可以保证令牌不变。

2) 微服务​​授权:

这是您遇到的第二种情况,您需要保证微服务之间的信任关系以及访问资源的授权。在这种情况下,您是否拥有微服务应该是客户端(充当用户)、身份验证服务(密钥斗篷、身份验证服务...),并且在向任何上游依赖项发送请求之前,应该对其进行身份验证,然后发送他的拥有自己的 JWT 令牌,这样目标微服务(被调用者)可以验证并允许或不允许调用者访问资源,然后检查最终用户凭据。

这种方法可以使用客户端凭据自动化流程 (https://oauth.net/2/grant-types/client-credentials) 来实现。

见这篇文章:https://developer.okta.com/blog/2018/04/02/client-creds-with-spring-boot

【讨论】:

【参考方案3】:

我想这个解决方案应该是JWT应该传递给网关层/聚合器/外观层。

在这一层,只需解码 JWT 并将数据设置在 DTO(任何 Java 类)中,这样就可以轻松访问。

现在,当需要将此信息传递给任何服务时,这些信息应该作为参数传递,因为无论如何服务层的 API 应该是通用的。

现在如果你想建立信任的黑白服务,你可以简单地检查参数,因为服务无论如何都不应该暴露在聚合器之外。

希望我说得通。

【讨论】:

您需要将 JWT 转换为 DTO 吗? JWT 是一种众所周知的结构,每个微服务都可以从中提取它需要的声明。您不需要支持额外的 DTO 类。

以上是关于微服务方法之间的身份验证的主要内容,如果未能解决你的问题,请参考以下文章

使用 SAML 和身份提供者的微服务身份验证

如何使用 OAuth2 保护 2 个 Spring Boot 微服务之间的通信?

使用 OAuth2/OpenId Connect 和微服务进行身份验证和授权

如何在 Java 11 客户端 - MongoDB 4.4 (SSL) 之间进行身份验证?

您应该如何处理跨微服务的身份验证和共享用户信息?

使用 jwt 在微服务中进行身份验证