Spring RestTemplate and Proxy Auth
Asked Answered
S

4

28

I'm trying to do REST calls with Spring. As I understand, the right way to go is using RestTemplate(?). Problem is, I'm behind a proxy.

This is my code right now:

SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
InetSocketAddress address = new InetSocketAddress(host, 3128);
Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
factory.setProxy(proxy);

RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(factory);

It seems to work, but I need to authenticate at the proxy, but how is this done? The Proxy type as well as the SimpleClientHttpRequestFactory type don't seem to handle credentials. Without credentials, I'm getting just 407...

Surge answered 7/7, 2015 at 15:39 Comment(0)
B
41

After quite a few different options I settled on The below code due to the ability to set the proxy for the RestTemplate at creation so I could refactor it into a separate method. Just to note it also has an additional dependency so keep that in mind.

private RestTemplate createRestTemplate() throws Exception {
    final String username = "myusername";
    final String password = "myPass";
    final String proxyUrl = "proxy.nyc.bigtower.com";
    final int port = 8080;

    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials( 
        new AuthScope(proxyUrl, port), 
        new UsernamePasswordCredentials(username, password)
    );

    HttpHost myProxy = new HttpHost(proxyUrl, port);
    HttpClientBuilder clientBuilder = HttpClientBuilder.create();

    clientBuilder.setProxy(myProxy).setDefaultCredentialsProvider(credsProvider).disableCookieManagement();

    HttpClient httpClient = clientBuilder.build();
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
    factory.setHttpClient(httpClient);

    return new RestTemplate(factory);
}

//Dependencies I used.

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.2</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.2.5.RELEASE</version>
</dependency>
Boycott answered 20/5, 2016 at 10:42 Comment(3)
What if I'm using Spring 3.0.1? I don't have the class HttpComponentsClientHttpRequestFactoryEvidentiary
This solution is not backwards compatible to Spring 3 you will need to create the request factory differently. I am not familiar with Spring 3 so yo will have to do some research. I strongly recommend using Spring 4 as Spring 5 is already on the way.Boycott
I know but unfortunately, on my project, is not possible upgrade a newer version . I turned around using an unauthenticated proxy and using SimpleClientHttpRequestFactory (Spring 3.0.5) instead of HttpComponentsClientHttpRequestFactory(Since Spring 3.1)Evidentiary
M
8

the code below worked for me.

RestTemplate restTemplate = new RestTemplate();

CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials( new AuthScope("proxyHost", "proxyPort"), new UsernamePasswordCredentials("proxyUser", "proxyPass") );
HttpClientBuilder clientBuilder = HttpClientBuilder.create();

clientBuilder.useSystemProperties();
clientBuilder.setProxy(new HttpHost("proxyHost", "proxyPort"));
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());

CloseableHttpClient client = clientBuilder.build();

HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(client);

restTemplate.setRequestFactory(factory);
Mocha answered 3/11, 2015 at 20:23 Comment(0)
I
0

If your proxy require basic auth, you can simply set the HTTP header Proxy-Authorization to handle authentication:

final SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
final InetSocketAddress address = new InetSocketAddress(host, 3128);
final Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
factory.setProxy(proxy);

final String username = "Aladdin";
final String password = "open sesame";

final RestTemplate restTemplate = new RestTemplateBuilder()
    .requestFactory(() -> factory)
    .defaultHeader(HttpHeaders.PROXY_AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((username + ':' + password).getBytes(StandardCharsets.UTF_8)))
    .build();

You don't need to use an additional dependency for that.

Illstarred answered 16/3, 2021 at 16:4 Comment(0)
F
0

@matthew-fontana's solution works excellently. However, in my case, I'm using HttpServiceProxyFactory with HttpExchange. Below is my version adapted for httpclient5:5.3.1.

BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
        new AuthScope(proxyUrl, proxyPort),
        new UsernamePasswordCredentials(proxyUsername, proxyPassword.toCharArray())
);

HttpHost proxy = new HttpHost(proxyUrl, proxyPort);

HttpClient httpClient = HttpClientBuilder
        .create()
        .setProxy(proxy)
        .setDefaultCredentialsProvider(credentialsProvider)
        .disableCookieManagement().build();

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);

RestClient restClient = RestClient
        .builder()
        .baseUrl(baseUrl)
        .requestFactory(requestFactory)
        .build();
Fendley answered 6/6, 2024 at 4:11 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.