微服务到微服务调用,来自 queue 消息的授权

Microservice to Microservice calls, authorization from a queue message

上下文: 我正在创建一个云平台来支持具有 SSO 的多个应用程序。我正在使用 Keycloak 进行身份验证 并使用 Netflix Zuul 进行授权(API 网关)通过 Keycloak Spring 安全适配器.

每个微服务都需要一个授权 header,其中包含一个有效的 JWT,它将从中获取用户名 (sub) 来处理请求。每个 microservice-to-microservice 调用都应该首先通过 Netflix Zuul,传递授权 header 以保持无状态验证。该策略允许每个微服务知道谁是间接调用微服务的用户(子)。

Problem/Question 1: 如果从 queue 消息调用微服务会发生什么?我的一个想法是在 queue 中存储与消息 + userInfo 相关的信息,并创建一个专用的微服务来处理这种消息,通过这种方法,这个特殊的微服务应该从 queue 并处理消息。

UPDATE 1: Per an email reply from another forum, storing the JWT in a queue isn't a good idea, since it could be mined easily.

Problem/Question 2: 但是,如果之前的特殊微服务想要调用另一个希望在 header 中接收 JWT 的普通微服务,会发生什么?这个特殊的微服务是否应该自己创建一个 JWT 来模拟用户并能够调用常规微服务?

我想到的另一个解决方案是将原始 JWT 存储在 queue 中,但是,如果 queue 稍后调用特殊微服务会发生什么情况?就在 JWT 不再有效(过期)之后,调用的微服务将拒绝请求?

可能的解决方案:(根据 João Angelo 的讨论更新,见下文)

I should authenticate the requests from my users (Authorization code flow) and my services (Client credentials grant), both requests should contain user information in the payload. When the request it comes from the user, I need to validate that the payload user info match with the JWT claims. When the request comes from a service, I just need to trust in that service (as long as it is under my control).

非常感谢您的帮助。谢谢

免责声明:我从未使用过 Keycloak,但标签 wiki 说它符合 OAuth2,所以我相信该信息。


从高层次的角度来看,您似乎有两个要求:

  1. 验证最终用户在使用您的系统时触发的操作。
  2. 验证您的系统在未知时间触发的操作,并且不需要最终用户在线。

你已经遇到了第一个,依赖于基于令牌的身份验证系统,我会为第二点做完全相同的事情,唯一的区别是令牌将颁发给您的系统使用 OAuth2 客户端凭据授予 而不是针对有最终用户的场景的其他授予。

(来源:Client Credentials Grant

在您的情况下,Keycloak 将扮演 Auth0 的角色,您的客户端应用程序是微服务,可以维护用于在授权服务器中验证自身并获取访问令牌的客户端机密。

要记住的一件事是,如果您的系统依赖于 sub 声明的不仅仅是身份验证和授权,那么您可能需要进行一些调整 .例如,我见过执行操作 A 需要知道它针对用户 X 和 Y 的系统,但该操作的有效负载只接收用户 Y 并假定用户 X 是当前经过身份验证的主体。当一切都是同步的时,这工作得很好,但仅仅通过切换有效负载来指定两个用户将意味着该操作可以由系统认证的主体异步完成。

一个常见的设置是 API gateway 通过他们的 JWT 验证所有传入的请求。 API 网关验证 JWT 的签名(或对加密的 JWT 进行解密),检查到期时间等,并从中提取范围和用户 ID (sub)。

然后它将范围与每个微服务的一组定义范围进行比较,如果该范围提供用户(主题)访问权限,则将请求转发到微服务。用户 ID(JWT 中的 sub)以及存储在 JWT 中的其他所需信息被放置在自定义请求 headers 中,例如 X-IGNACIO-SUBJECT

正如您所说,您的微服务使用 JWT 进行身份验证,它始终通过网关,这样您就可以实际使用 FEIGN CLIENT 的概念。 Feign as rest client example.