Spring security 微服务到微服务调用,来自队列消息的授权

Spring security 微服务到微服务调用,来自队列消息的授权,spring-security,jwt,microservices,netflix-zuul,keycloak,Spring Security,Jwt,Microservices,Netflix Zuul,Keycloak,上下文:我正在创建一个云平台,以支持具有SSO的多个应用程序。我正在使用keydove进行身份验证并使用Netflix Zuul通过keydove-Spring安全适配器进行授权(API网关) 每个微服务都需要一个授权头,其中包含一个有效的JWT,它将从中获取用户名(sub)来处理请求。每个微服务到微服务的调用都应该首先通过Netflix Zuul,传递授权头以维护无状态验证。该策略允许每个微服务知道谁是间接调用微服务的用户(sub) 问题/问题1:如果从队列消息调用微服务,会发生什么?我的一个

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

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

问题/问题1:如果从队列消息调用微服务,会发生什么?我的一个想法是在队列中存储与消息+用户信息相关的信息,并创建一个专用的微服务来处理此类消息,通过这种方法,这个特殊的微服务应该从队列中读取用户信息并处理消息


更新1:根据另一个论坛的电子邮件回复,将JWT存储在队列中不是一个好主意,因为它很容易被挖掘

问题/问题2:但是,如果前一个特殊的微服务想要调用另一个正常的微服务,而该微服务希望在头中接收JWT,该怎么办?这个特殊的微服务是否应该自己创建一个JWT来模拟用户并能够调用常规的微服务

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

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

我应该验证来自我的用户(授权代码流)和我的服务(客户端凭据授予)的请求,这两个请求都应该在负载中包含用户信息。当请求来自用户时,我需要验证有效负载用户信息是否与JWT声明匹配。当请求来自某个服务时,我只需要信任该服务(只要它在我的控制之下)


我将非常感谢你的帮助。谢谢。

免责声明:我从未使用过KeyClope,但是标签wiki说它符合OAuth2,所以我相信这些信息


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

  • 验证最终用户在使用您的系统时触发的操作
  • 在未知时间和最终用户不需要联机的情况下,对系统触发的操作进行身份验证
  • 通过依赖基于令牌的身份验证系统,您已经遇到了第一个问题,对于第二点,我也会这样做,唯一的区别是,令牌将使用OAuth2客户机凭据授权(而不是针对存在最终用户的场景的其他授权)颁发给您的系统

    (来源:)

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


    需要记住的一点是,如果您的系统所依赖的
    子声明远远超过了身份验证和授权,那么您可能需要进行一些调整。例如,我看到过这样的系统:执行动作A需要知道它是针对用户X和Y的,但该动作的有效负载只接收到用户Y,并假设用户X是当前经过身份验证的主体。当所有内容都是同步的时,这种方法可以很好地工作,但仅通过切换有效负载来指定两个用户将意味着操作可以由经过系统身份验证的主体异步完成。

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


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

    中,正如您所说,您的微服务使用JWT进行身份验证,该验证始终通过网关,这样您就可以实际使用外部客户端的概念。
    .

    你好,乔,我理解,因此,1)微服务应始终期望用户或其他服务提供JWT。我刚刚做了测试,发现微服务JWT与用户JWT之间的一些差异并不包含声明,它还包含一个额外的“clientId”字段,因此,如果JWT包含一个“clientId”,那么它不是用户而是服务。或者,我可以依赖于“aud”字段,如果“aud”对应于客户端名称来验证用户,那么它是一个用户,如果不是,则是另一个服务。2)似乎我需要始终发送有效负载中的用户ID,以便服务能够以透明的方式处理请求(服务或用户呼叫),如果我确定呼叫来自用户“aud”或“clientId”我可以用“sub”或“preferred\u”用户名验证有效负载字段“确保有效负载的值与执行操作的用户相对应。但是,在服务的情况下,我只需要信任在有效负载中指定的用户?是的,这将是一种方法,当输入来自用户到mak时验证输入