WebClient代理配置不适用于oAuth2

时间:2019-12-02 21:49:33

标签: java spring-boot oauth-2.0 spring-webflux spring-webclient

我已经实现了具有授予类型“客户端凭据”的webclient和oAuth2。我必须使用代理访问局。但是webclient没有使用我配置的主机。

from pyspark.sql import Row

MyOuterROW = Row('_xmlns', '_Version', 'MyIds')
MyInnerRow = Row('_ID', '_ID_Context', '_Type')

myRow = MyOuterROW( 
    "http://some.where.com", 
    12.3, 
    [ 
        MyInnerROW("XY", "Exxwhy", 9), 
        MyInnerROW("9152", "LNUMB", 21) 
    ] 
)              
print(myRow)
#Row(_xmlns='http://some.where.com', _Version=12.3, MyIds=[Row(_ID='XY', _ID_Context='Exxwhy', _Type=9), Row(_ID='9152', _ID_Context='LNUMB', _Type=21)])

rdf = spark.createDataFrame([myRow], schema=myschema_xb)

如果我使用系统配置代理,它可以正常工作:

HttpClient httpClient = HttpClient.create()
.tcpConfiguration(tcpClient -> tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeout)
.doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(readTimeout, TimeUnit.MILLISECONDS)))
.proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP).host(proxyHost).port(proxyPort)));

但是我不能在云上使用System属性。请建议我一些解决方法或任何解决方案。

我收到以下例外情况: “ org.springframework.security.oauth2.core.OAuth2AuthorizationException:[invalid_token_response]尝试检索OAuth 2.0访问令牌响应时发生错误:POST请求\” https://tokenURL“时发生I / O错误:api.uat .equifax.com;嵌套的异常是java.net。 UnknownHostException :resourseURL \ r \ n \ tat org.springframework.security.oauth2.client.endpoint.DefaultClientCredentialsTokenResponseClient.getTokenResponse(DefaultClientCredentialsTokenResponseClient.java:79) \ r \ n \ tat ...“

1 个答案:

答案 0 :(得分:0)

老问题,但它仍然是我们找到的第一个 stackoverflow 条目,所以我们决定document our solution

我们偶然发现了同样的问题。 OAuth2AuthorizationException 异常表示授权请求过程中出现问题。在对 spring-security-oauth2-client 源代码进行一些挖掘后,我们发现授权请求使用的是与资源请求不同的客户端。您只需为资源客户端设置代理。

授权请求正在使用 RestTemplate。以下代码片段展示了我们如何创建使用代理的自定义 RestTemplate 并将其添加到我们的 OAuth2AuthorizedClientManager。

@Bean 
public OAuth2AuthorizedClientManager authorizedClientManager( 
    final ClientRegistrationRepository clientRegistrationRepository, 
    final OAuth2AuthorizedClientService authorizedClientService) { 
 
    // Create RestTemplate that will be used for the authorization request
    // It's mandatory to add FormHttpMessageConverter and OAuth2AccessTokenResponseHttpMessageConverter
    // See javadoc from DefaultClientCredentialsTokenResponseClient.setRestOperations(RestOperations restOperations)
    // for further information
    RestTemplate restTemplate = new RestTemplate( 
        Arrays.asList(new FormHttpMessageConverter(), new OAuth2AccessTokenResponseHttpMessageConverter())); 
    restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler()); 
 
 
    // set up proxy for RestTemplate
    final HttpClientBuilder clientBuilder = HttpClientBuilder.create(); 
    clientBuilder.useSystemProperties(); 
    clientBuilder.setProxy(new HttpHost(proxyConfigDO.getHost(), proxyConfigDO.getPort())); 
 
    final CredentialsProvider credsProvider = new BasicCredentialsProvider(); 
    credsProvider.setCredentials( 
        new AuthScope(proxyConfigDO.getHost(), proxyConfigDO.getPort()), 
        new UsernamePasswordCredentials(proxyConfigDO.getUser(), proxyConfigDO.getPassword())); 
    clientBuilder.setDefaultCredentialsProvider(credsProvider); 
    clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); 
 
    final CloseableHttpClient client = clientBuilder.build(); 
    final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); 
    factory.setHttpClient(client); 
 
    restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory)); 
 
    // Create new client and pass our custom resttemplate 
    final var tokenResponseClient = new DefaultClientCredentialsTokenResponseClient(); 
    tokenResponseClient.setRestOperations(restTemplate); 
 
    // Create ClientCredentialsOAuth2AuthorizedClientProvider and override default setAccessTokenResponseClient
    // with the one we created in this method
    final var authorizedClientProvider = new ClientCredentialsOAuth2AuthorizedClientProvider(); 
    authorizedClientProvider.setAccessTokenResponseClient(tokenResponseClient); 
 
    final var authorizedClientManager = 
        new AuthorizedClientServiceOAuth2AuthorizedClientManager( 
            clientRegistrationRepository, authorizedClientService); 
    authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); 
 
    return authorizedClientManager; 
}