0

I have implemented webclient and oAuth2 with grant type Client Credentials. I must use proxy to access bureau. But webclient is not using the host which I have configured.

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)));

its working fine if I configure proxy with system :

System.setProperty("proxyHost", "host);
System.setProperty("proxyPort", "8080");

But I can't use System property over the cloud. Please suggest me some work around or any solution.

I am getting below exception: "org.springframework.security.oauth2.core.OAuth2AuthorizationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: I/O error on POST request for \"https://tokenURL": api.uat.equifax.com; nested exception is java.net.UnknownHostException: resourseURL\r\n\tat org.springframework.security.oauth2.client.endpoint.DefaultClientCredentialsTokenResponseClient.getTokenResponse(DefaultClientCredentialsTokenResponseClient.java:79)\r\n\tat ..."

6
  • the error msg is quite clear, Unknown host "tokenURL" that doesn't look like a valid hostname to me "host doesn't look valid Commented Dec 3, 2019 at 12:01
  • Thanks for your response Adolf, actually in my code I am using actual hostname but due to some security reason I am not pasting it over here. proxy.type(ProxyProvider.Proxy.HTTP).host(proxyHost).port(proxyPort)) Commented Dec 3, 2019 at 18:57
  • well as i said before, the error msg is quite clear, UnknownHostException Commented Dec 3, 2019 at 20:59
  • Yes you are right Adolf but I don't get this unknownHostException when I set the proxies by using System.setProperty as mentioned above. I do not want to set the proxies with System and I want to follow the conventional approach by setting the proxies with HttpClient alone. When we do this I get UnknownhostException. Suggest me some work around or any fix if possible. Commented Dec 4, 2019 at 11:45
  • my suggestion is to debug the application/source code and check what value actually is there when it throws the exception. Since the error does not lie in the code you have posted. Commented Dec 4, 2019 at 11:53

1 Answer 1

2

Old question but it was still the first stackoverflow entry we found so we decided to document our solution.

We stumbled across the same problem. The exception OAuth2AuthorizationException indicates that the problem occurs during the authorization request. After some digging in the spring-security-oauth2-client sources, we found out that the authorization request is using a different client than the resource request. You only set the proxy for the resource client.

The authorization request is using a RestTemplate. The following code snippet shows how we created a custom RestTemplate that is using a proxy and added it to our 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; 
}
Sign up to request clarification or add additional context in comments.

3 Comments

Hey Max, thanks for sharing this. When I try your solution, I get the message: a bean of type 'org.springframework.security.oauth2.client.registration.ClientRegistrationRepository' that could not be found. I feel so close to the solution, but I do not understand why this bean is not created by spring based on my configuration (with the spring.security.oauth2.client.registration set). Any idea?
Hi Purfakt, I'd guess that you're missing a spring dependency. We don't create the ClientRegistrationRepository bean manually.
it worked for me, thanks ! I had to add this dependency : 'org.apache.httpcomponents:httpclient:4.5.13'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.