How to use a Proxy with RestTemplates

Published
Updated

I had an issue the other week where I needed my Spring Boot App’s RestTemplate to route requests through a corporate proxy… But only for certain host names. It turns out this is a pretty painless and easy configuration using Spring’s RestTemplateCustomizer. If your proxy requires Basic Auth, this will also selectively provide your credentials using Basic Auth but it can also be easily configured to use another authentication mechanism.

First, you need to create a class that will define Spring’s RestTemplateCustomizer. Then you configure an HttpClientBuilder that will be used to specify Spring’s proxy details, credentials provider, as well as a custom Route Planner that determines when a proxy should actually be used.

public class MyRestTemplateCustomizer implements RestTemplateCustomizer {

  @Override
  public void customize(RestTemplate restTemplate) {
    
    // Configure your proxy server here
    HttpHost proxyHost = new HttpHost("http", "myproxy.internal.com", 8080);
    
    // Configure the client builder with your custom route planner
    HttpClientBuilder clientBuilder = new HttpClientBuilder.create();
    clientBuilder.setRoutePlanner(new CustomRoutePlanner(proxyHost));
    
    // Configure your proxy credentials
    BasicCredentialsPreovider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(new AuthScope(proxyHost), 
        new UsernamePasswordCredentials("proxyUsername", "proxyPassword"));
        
        
    clientBuilder.setDefaultCredentialsProvider(credentialsProvider);
    
    restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(clientBuilder.build()));
  }
  
  static class CustomRoutePlanner extends DefaultProxyRoutePlanner {
    CustomRoutePlanner(HttpHost host) {
      super(host);
    }
    
    @Override
    protected HttpHost determineProxy(HttpHost target, HttpContext context) throws HttpException {
      if (target.getHostName().contains("domain-requiring-proxy.com")) {
        // Use our configured proxy
        return super.determineProxy(target, context);
      } else {
        // Don't use a proxy.
        return null;
      }
    }
  }
}