背景信息:我正在创建一个支持多个SSO应用程序的云平台。我正在使用 Keycloak进行身份验证, Netflix Zuul进行授权(API网关)至 Keycloak Spring Security Adapter 。
每个微服务都需要一个Authorization标头,其中包含一个有效的JWT,用户名(sub)将从该标头处理请求。每个微服务到微服务调用应首先通过Netflix Zuul,传递Authorization标头以维持无状态验证。该策略允许每个微服务器知道谁是间接调用微服务的用户(子)。
问题/问题1:如果从队列消息中调用微服务会发生什么?我的一个想法是在队列中存储与消息+ userInfo相关的信息,并创建一个专用的微服务来处理这种消息,这种特殊的微服务应该从队列中读取userInfo并处理消息
更新1:根据另一个论坛的电子邮件回复,将JWT存储在队列中并不是一个好主意,因为它可以轻松挖掘。
问题/问题2:但是,如果之前的特殊微服务想要调用另一个期望在标头中接收JWT的普通微服务会发生什么?这个特殊的微服务是否应该由他自己创建一个JWT模仿用户并能够调用常规的微服务?
我认为另一种解决方案是将原始JWT存储在队列中,但是,如果队列稍后调用特殊微服务会发生什么?在JWT不再有效(它已过期)之后,被调用的微服务将拒绝该请求吗?
可能的解决方案:(根据JoãoAngelo讨论更新,见下文)
我应该对用户(授权代码流)和我的服务(客户端凭据授予)的请求进行身份验证,这两个请求都应包含有效负载中的用户信息。当请求来自用户时,我需要验证有效负载用户信息是否与JWT声明匹配。当请求来自服务时,我只需要信任该服务(只要它在我的控制之下)。
我非常感谢你的帮助。感谢。
答案 0 :(得分:5)
免责声明:我从未使用过Keycloak,但标签维基表示它符合OAuth2标准,因此我相信这些信息。
在一个非常高级的视图中,您似乎有两个要求:
您已经通过依赖基于令牌的身份验证系统遇到了第一个,并且我会对第二点做同样的事情,唯一的区别是令牌会被发送到您的系统使用OAuth2客户端凭据授予,而不是针对存在最终用户的方案的其他授权。
在您的情况下,Keycloak将扮演Auth0的角色,您的客户端应用程序是微服务,可以维护用于在授权服务器中验证自身的客户机密码并获取访问令牌。
要记住的一件事是,如果您的系统依赖sub
声明而不仅仅是身份验证和授权,那么您可能需要进行一些调整。例如,我已经看到执行操作A的系统需要知道它是针对用户X和Y的,但是操作的有效负载仅接收用户Y并且假设用户X是当前经过身份验证的主体。当一切都是同步的时,这种方法很好,但仅通过切换有效负载来指定两个用户就意味着该操作可以由系统认证的主体异步完成。
答案 1 :(得分:0)
一个常见的设置是让API gateway验证其JWT的所有传入请求。 API网关验证JWT的签名(或为加密的JWT解密它),检查到期时间等,并从中提取范围和用户ID(子)。
然后,它将范围与每个micrto服务的一组已定义范围进行比较,如果范围提供用户(主题)访问,则将请求转发给微服务。用户ID(JWT中的子)以及存储在JWT中的其他所需信息放在自定义请求标头中,如X-IGNACIO-SUBJECT答案 2 :(得分:0)
正如您所说,您的微服务使用JWT进行身份验证,该身份验证始终通过网关,因此您实际上可以使用FEIGN CLIENT的概念。 Feign as rest client example。