From http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/ with HttpClient 4.3 edits:
Both Spring 3.0 and 3.1 and now 4.x have very good support for the Apache HTTP libraries:
- Spring 3.0, the
CommonsClientHttpRequestFactory
integrated with the now end of lifed HttpClient 3.x
- Spring 3.1 introduced support for the current HttpClient 4.x via
HttpComponentsClientHttpRequestFactory
(support added in the JIRA SPR-6180)
- Spring 4.0 introduced async support via the
HttpComponentsAsyncClientHttpRequestFactory
Let’s start setting things up with HttpClient 4 and Spring 4.
The RestTemplate
will require an HTTP request factory – a factory that supports Basic Authentication – so far, so good. However, using the existing HttpComponentsClientHttpRequestFactory
directly will prove to be difficult, as the architecture of RestTemplate
was designed without good support for HttpContext
– an instrumental piece of the puzzle. And so we’ll need to subclass HttpComponentsClientHttpRequestFactory
and override the createHttpContext
method: (taken from soluvas-framework on GitHub)
package org.soluvas.commons.util;
import java.net.URI;
import javax.annotation.Nullable;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.HttpClient;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
* From http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/
*
* <p>And with that, everything is in place – the {@link RestTemplate} will now be able to support the Basic Authentication scheme; a simple usage pattern would be:
*
* <pre>
* final AuthHttpComponentsClientHttpRequestFactory requestFactory = new AuthHttpComponentsClientHttpRequestFactory(
* httpClient, host, userName, password);
* final RestTemplate restTemplate = new RestTemplate(requestFactory);
* </pre>
*
* And the request:
*
* <pre>
* restTemplate.get("http://localhost:8080/spring-security-rest-template/api/foos/1", Foo.class);
* </pre>
*
* @author anton
*/
public class AuthHttpComponentsClientHttpRequestFactory extends
HttpComponentsClientHttpRequestFactory {
protected HttpHost host;
@Nullable
protected String userName;
@Nullable
protected String password;
public AuthHttpComponentsClientHttpRequestFactory(HttpHost host) {
this(host, null, null);
}
public AuthHttpComponentsClientHttpRequestFactory(HttpHost host, @Nullable String userName, @Nullable String password) {
super();
this.host = host;
this.userName = userName;
this.password = password;
}
public AuthHttpComponentsClientHttpRequestFactory(HttpClient httpClient, HttpHost host) {
this(httpClient, host, null, null);
}
public AuthHttpComponentsClientHttpRequestFactory(HttpClient httpClient, HttpHost host,
@Nullable String userName, @Nullable String password) {
super(httpClient);
this.host = host;
this.userName = userName;
this.password = password;
}
@Override
protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(host, basicAuth);
// Add AuthCache to the execution context
HttpClientContext localcontext = HttpClientContext.create();
localcontext.setAuthCache(authCache);
if (userName != null) {
BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(userName, password));
localcontext.setCredentialsProvider(credsProvider);
}
return localcontext;
}
}
It is here – in the creation of the HttpContext
– that the basic authentication support is built in. As you can see, doing preemptive Basic Authentication with HttpClient 4.x is a bit of a burden: the authentication info is cached and the process of setting up this authentication cache is very manual and unintuitive.
And with that, everything is in place – the RestTemplate
will now be able to support the Basic Authentication scheme; a simple usage pattern would be:
final AuthHttpComponentsClientHttpRequestFactory requestFactory =
new AuthHttpComponentsClientHttpRequestFactory(
httpClient, host, userName, password);
final RestTemplate restTemplate = new RestTemplate(requestFactory);
And the request:
restTemplate.get(
"http://localhost:8080/spring-security-rest-template/api/foos/1",
Foo.class);
For an in depth discussion on how to secure the REST Service itself, check out this article.