【问题标题】:How to use Eureka Names with OAuth2RestTemplate如何在 OAuth2RestTemplate 中使用 Eureka 名称
【发布时间】:2018-10-04 11:16:15
【问题描述】:

我正在使用 OAuth2RestTemplate 来通过 REST 请求传递 oauth 令牌。但是,我现在需要对我的网址进行硬编码,例如

restTemplate.postForLocation("http://localhost:5555/other-service2/message", "Message")

而当我使用自行创建的带注释的功能区(使用 @LoadBalanced)RestTemplate bean 时,我可以执行类似的操作

 restTemplate.postForLocation("http://service1/other-service2/message", "Message")

这是因为当您使用 LoadBalanced 时,它会自动将其设为 Ribbon Rest 模板,让您可以使用服务发现功能或 Eureka,但是当您使用 @Loadbalanced 注释 OAuth2RestTemplate bean 时,它会在尝试使用 OAuth2RestTemplate 时的运行时,它说

  o.s.b.a.s.o.r.UserInfoTokenServices      : Could not fetch user details: class java.lang.IllegalStateException, No instances available for localhost

我的 OAuth2RestTemplate 创建看起来像

@LoadBalanced
@Bean
public OAuth2RestTemplate restTemplate(final UserInfoRestTemplateFactory factory) {
    final OAuth2RestTemplate userInfoRestTemplate = factory.getUserInfoRestTemplate();
    return userInfoRestTemplate;
}

如何在 OAuth2RestTemplate 上使用 Eureka 功能区的服务发现功能和负载平衡功能?

【问题讨论】:

    标签: java spring-boot spring-security spring-security-oauth2 netflix-eureka


    【解决方案1】:

    我认为这是你可以尝试的。

    在我的项目中,我们还使用 OAuth2、Eureka、Ribbon 让微服务相互通信。为了将 Ribbon 与 OAuth2 一起使用,我们采用的方法有点不同。

    首先我们保持 restTemplate 不变。

      @LoadBalanced
      @Bean
      public RestTemplate restTemplate() {
    

    但是,我们创建了 FeignClientIntercepter 实现 RequestIntercepter,它在通过 restTemplate 发出请求时为 OAuth 设置授权令牌。

      @Component
      public class UserFeignClientInterceptor implements RequestInterceptor {
    
        private static final String AUTHORIZATION_HEADER = "Authorization";
        private static final String BEARER_TOKEN_TYPE = "Jwt";
    
        @Override
        public void apply(RequestTemplate template) {
          SecurityContext securityContext = SecurityContextHolder.getContext();
          Authentication authentication = securityContext.getAuthentication();
    
          if (authentication != null && authentication
              .getDetails() instanceof OAuth2AuthenticationDetails) {
            OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication
              .getDetails();
            template.header(AUTHORIZATION_HEADER,
                String.format("%s %s", BEARER_TOKEN_TYPE, details.getTokenValue()));
          }
        }
      }
    

    如果你尝试创建 spring msa 项目,我更喜欢使用 Feign-client 而不是 restTemplate。

    @FeignClient("your-project-name")
    public interface YourProjectClient {
    
      @GetMapping("your-endpoint")
      JsonObject getSomething();
    

    【讨论】:

    • 非常好,明天上班时会测试,但它似乎是一个可行的解决方案,因此被接受
    • 嗯.. 实际上似乎请求没有被拦截。还有什么我需要更改或开启的吗?
    • 我是否需要用那些 feign @FeignClient("endpoint") 注释标记我的所有端点?
    • 很抱歉迟到了您的问题。明天,我会给你更详细的例子。
    • 太棒了,有时间我会在工作中试一试并提供反馈!
    猜你喜欢
    • 2020-10-15
    • 2015-03-07
    • 2017-11-02
    • 2016-12-07
    • 2016-12-25
    • 2018-04-15
    • 2020-05-16
    • 1970-01-01
    • 2012-04-08
    相关资源
    最近更新 更多