aks2012
aks2012

Reputation: 121

Proxy configuration in OAuth2RestTemplate

I need to consume an API which is secured by OAuth2. For that I am using OAuth2RestTemplate. But am getting below error:

java.net.ConnectException: Connection timed out: connect

This is happening due to proxy issue. I Know how to set proxy in RestTemplate :

 SimpleClientHttpRequestFactory clientHttpRequestFactory = new       SimpleClientHttpRequestFactory();
 Proxy proxy = new Proxy(Proxy.Type.HTTP, new      InetSocketAddress("Proxy host", 8080));

clientHttpRequestFactory.setProxy(proxy); RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);

The same way I tried to set for OAuth2RestTemplate :

@Bean
public OAuth2RestOperations restTemplate(OAuth2ClientContext oauth2ClientContext) {
    OAuth2RestTemplate client =  new OAuth2RestTemplate(resource(), oauth2ClientContext);
    SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
    clientHttpRequestFactory.setProxy(proxy);
    client.setRequestFactory(clientHttpRequestFactory);
    return client;
}

But it is not working and giving "Connection timed out" exception. This is happening because of this first line OAuth2RestTemplate client = new OAuth2RestTemplate(resource(), oauth2ClientContext); which tries to get Access token that means there also it needs proxy setting. if I add below lines then it works:

System.setProperty("https.proxyHost", "urproxy.com");
System.setProperty("https.proxyPort", "8080");

But I can not use System.setProperties("","") option as we do not have permission to set on tomcat server.

I researched but could not find any way to set proxy in OAuth2RestTemplate while creating this object.

Any help would be appreciated. Thanks

Upvotes: 8

Views: 7265

Answers (2)

Eelco
Eelco

Reputation: 79

This RestTemplate provides a workaround:

/**
 * An OAuth2RestTemplate with proxy support.
 * 
 * @author E.K. de Lang
 */
public class ProxySupportingOAuth2RestTemplate
    extends OAuth2RestTemplate
{
    private static final Logger LOG = LogFactory.getLogger(ProxySupportingOAuth2RestTemplate.class);

    private final SimpleClientHttpRequestFactory factory;

    public ProxySupportingOAuth2RestTemplate(OAuth2ProtectedResourceDetails resource, OAuth2ClientContext context,
            AccessTokenProvider accessTokenProvider)
    {
        super(resource, context);
        factory = new SimpleClientHttpRequestFactory();
        super.setRequestFactory(factory);
        super.setAccessTokenProvider(accessTokenProvider);

        // To fix issue: https://github.com/spring-projects/spring-security-oauth/issues/459 also set the factory of the token-provider.
        if (accessTokenProvider instanceof OAuth2AccessTokenSupport) {
            ((OAuth2AccessTokenSupport) accessTokenProvider).setRequestFactory(factory);
        }
        else {
            throw new UnsupportedOperationException("accessTokenProvider must extend OAuth2AccessTokenSupport");
        }
    }

    public void setProxy(Proxy proxy)
    {
        if (LOG.isDebugEnabled()) {
            LOG.debug("setProxy:" + proxy);
        }
        if (super.getRequestFactory() == factory) {
            factory.setProxy(proxy);
        }
        else {
            throw new UnsupportedOperationException("RequestFactory has changed.");
        }
    }
}

Upvotes: 0

kvy
kvy

Reputation: 141

OAuth2RestTemplate just creates a set of AccessTokenProvider to retrieve the token from authorization server according to different kinds of grant types. For example AuthorizationCodeAccessTokenProvider is used to retrieve access token with grant type authorization_code. The token providers themselves initiate some RestTemplate to send the request but do not use OAuth2RestTemplate just created. One way might resolve the issue. That is to create you own AccessTokenProvider and set the request factory.

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
Proxy proxy= new Proxy(Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
requestFactory.setProxy(proxy);      

AuthorizationCodeAccessTokenProvider authorizationCodeAccessTokenProvider = new AuthorizationCodeAccessTokenProvider();
authorizationCodeAccessTokenProvider.setRequestFactory(requestFactory);

ImplicitAccessTokenProvider implicitAccessTokenProvider = new ImplicitAccessTokenProvider();
implicitAccessTokenProvider.setRequestFactory(requestFactory);

AccessTokenProvider accessTokenProvider = new AccessTokenProviderChain(
Arrays.<AccessTokenProvider> asList(authorizationCodeAccessTokenProvider, implicitAccessTokenProvider));

OAuth2RestTemplate client = new OAuth2RestTemplate(github(), oauth2ClientContext);
client.setAccessTokenProvider(accessTokenProvider);

You could also add ResourceOwnerPasswordAccessTokenProvider and ClientCredentialsAccessTokenProvider to the OAuth2RestTemplate.

Upvotes: 14

Related Questions