Microservices 无法使用来自消息使用者的假客户端

Microservices 无法使用来自消息使用者的假客户端,microservices,jhipster,okta,spring-cloud-feign,feign,Microservices,Jhipster,Okta,Spring Cloud Feign,Feign,我用JHipster创建了一组三个微服务,并用Okta OAuth2自动验证进行了配置 我还添加了与RabbitMQ消息服务的集成,以便其中一个服务生成有关特定事件的消息,另一个使用这些消息来更新其数据库 现在,第二个服务(要完全更新其数据)需要来自第三个服务的信息,我想用FaignClient调用该服务,但它失败了,堆栈如下: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating b

我用JHipster创建了一组三个微服务,并用Okta OAuth2自动验证进行了配置

我还添加了与RabbitMQ消息服务的集成,以便其中一个服务生成有关特定事件的消息,另一个使用这些消息来更新其数据库

现在,第二个服务(要完全更新其数据)需要来自第三个服务的信息,我想用FaignClient调用该服务,但它失败了,堆栈如下:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.oauth2ClientContext': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:362)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:193)
at com.sun.proxy.$Proxy237.getAccessToken(Unknown Source)
at it.myefm.myspot.people.security.oauth2.AuthorizationHeaderUtil.getAuthorizationHeaderFromOAuth2Context(AuthorizationHeaderUtil.java:26)
at it.myefm.myspot.people.client.TokenRelayRequestInterceptor.apply(TokenRelayRequestInterceptor.java:23)
at feign.SynchronousMethodHandler.targetRequest(SynchronousMethodHandler.java:158)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:88)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:108)
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302)
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46)
... 113 more

Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
at org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:42)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350)
... 126 more
我认为问题在于,伪执行不是从web请求开始的,所以上下文中没有身份验证信息……对吗

是否有其他方法在服务之间访问我的数据?

问题在于您的TokenRelayRequestInterceptor试图从当前线程绑定的安全上下文解析身份验证信息

显然,当您处于消费者线程中时,默认情况下您没有此类信息,至少因此解析失败

您可以做以下几件事:

在事件中传递必要的信息对于事件源系统来说可能会有问题,如果它是访问令牌,因为它可能会过期 以某种方式试图伪造第三个服务接受的访问令牌 在用户端,您可以使用拦截器所需的信息手动设置SecurityContext,也可以忘记用户端的拦截器,手动提供第三方服务所需的数据。我猜这只是一个授权标头

更新
您还可以在第三个服务中创建一个内部端点,它根本不需要任何身份验证,外部无法访问。

您可以使用客户端凭据在第二个和第三个服务之间进行通信。这里有一篇博文解释了更多:谢谢!我使用了你建议的第一种方法。通过将用户信息与事件一起传递,我可以在外部客户端中设置SecurityContext。我们没有系统生成的事件,因此….它现在可以工作;很高兴我能帮忙。在这种情况下,请接受答案,以便其他人在遇到相同问题时可以从中受益。