无法将 @LoadBalanced 与在 ClientCredentials 上配置的 OAuth2RestTemplate 一起使用

Posted

技术标签:

【中文标题】无法将 @LoadBalanced 与在 ClientCredentials 上配置的 OAuth2RestTemplate 一起使用【英文标题】:Unable to use @LoadBalanced with OAuth2RestTemplate configured on ClientCredentials 【发布时间】:2018-11-02 17:11:33 【问题描述】:

我想使用 OAuth2 ClientCredentials 流在两个资源服务器之间进行服务间通信。一切正常,除了我无法在对远程资源服务器的 OAuth2RestTemplate 调用中使用服务名称(功能区负载均衡器功能)而不是主机名。

我的一个资源服务器(调用另一个资源服务器)具有以下配置:

Spring Boot 1.5.13
Spring Cloud Edgware.SR3

build.gradle 包含 eureka 和 Ribbon 的条目

compile('org.springframework.cloud:spring-cloud-starter-ribbon')
compile('org.springframework.cloud:spring-cloud-starter-eureka')


@Configuration
class RestTemplateConfig 

    @Bean
    @ConfigurationProperties("security.oauth2.client")
    public ClientCredentialsResourceDetails oauth2ClientCredentialsResourceDetails() 
        return new ClientCredentialsResourceDetails();
    

    @LoadBalanced
    @Bean(name = "oauthRestTemplate")
    public OAuth2RestOperations oAuthRestTemplate(ClientCredentialsResourceDetails oauth2ClientCredentialsResourceDetails) 
        return new OAuth2RestTemplate(oauth2ClientCredentialsResourceDetails);
    

使用此 OAuth2RestTemplate 的服务

@Service
class TestService 

    @Autowired
    @Qualifier("oauthRestTemplate")
    private OAuth2RestOperations oAuth2RestOperations;

    public void notifyOrderStatus(long orderId, OrderStatus newStatus) 
        oAuth2RestOperations.exchange("http://notification-service/api/order/id/status/status", HttpMethod.POST, null, Void.class, orderId, newStatus.name());
    

使用服务名称(即http://notification-service)而不是远程资源服务器的实际主机名和端口调用远程服务时出现异常。如果我使用实际的主机名 + 端口,那么一切正常,但我不希望我的一个资源知道另一个资源服务器的主机/发布。

例外:

Caused by: java.net.UnknownHostException: notification-service 

我有几个问题:

    如果我的 RestTemplate 使用 @LoadBalanced 注释,那么一切正常。 OAuth2RestTemplate 是否支持此注释,我们可以使用服务名称而不是主机名吗?如果是,任何参考或文档将不胜感激。 使用 oauth2 客户端凭据来确保两个资源服务器之间的服务间安全性是个好主意吗?我在文档中没有看到任何相同的示例?

【问题讨论】:

【参考方案1】:

@LoadBalancedRestTemplate 在我们使用RestTemplateCustomizer 自定义新创建的OAuth2RestTemplate 时起作用,如下代码所示:

@Bean(name = "MyOAuthRestTemplate")
@LoadBalanced
public OAuth2RestOperations restTemplate(RestTemplateCustomizer customizer, ClientCredentialsResourceDetails oauth2ClientCredentialsResourceDetails) 
    OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(oauth2ClientCredentialsResourceDetails);
    customizer.customize(restTemplate);
    return restTemplate;

使用此 RestTemplate 使用服务名称而不是实际主机名可以正常工作。

【讨论】:

这对你有用吗?我试过这个,我得到错误:java.net.UnknownHostException:oauth-server 我正在使用 Eureka Discovered OAuth2 服务器:clientCredentialsResourceDetails.setAccessTokenUri("oauth-server/oauth/token"); 这终于解决了我的问题:***.com/questions/62574591/…

以上是关于无法将 @LoadBalanced 与在 ClientCredentials 上配置的 OAuth2RestTemplate 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

RestTemplate对象与LoadBalanced注解

RestTemplate对象与LoadBalanced注解

ideal @loadbalanced 找不到

无法与在 0.0.0.0:8443 上侦听的应用程序建立连接

无法与在 0.0.0.0:8443 上侦听的应用程序建立连接

无法与在 EC2 上运行的 Laravel Websockets 建立连接