I am currently working on integration of a third party application with our local reporting system. I would like to implement REST calls with basic authentication but facing
Since Spring 4.3.1 there is a simplier way using BasicAuthorizationInterceptor, which is also independent of underlying http client used in RestTemplate
.
The example that uses RestTemplateBuilder from spring-boot to add BasicAuthorizationInterceptor
to RestTemplate
:
@Configuration
public class AppConfig {
@Bean
public RestTemplate myRestTemplate(RestTemplateBuilder builder) {
return builder
.rootUri("http://my.cool.domain/api/")
.basicAuthorization("login", "password")
.build();
}
}
This way any request sent using myRestTemplate
bean instance will include given basic authorization header. So be careful to not use the same RestTemplate
bean instance to send requests to foreign domains. The rootUri
is partially protects from this, but you can always pass the absolute URL when making the request using RestTemplate
instance, so be careful!
If you are not using spring-boot
, you can also manually add this interceptor to your RestTemplate
following this answer.
Why not check the Spring 4 APIs to see which classes implement the required interface, namely ClientHttpRequestFactory?
As you'll see from the Javadoc, most likely you want HttpComponentsClientHttpRequestFactory, which uses the client from Apache's HttpComponents, the successor to the old commons HttpClient
.
If you prefer simple over complex, then just set the header
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + Base64.getUrlEncoder().encodeToString("myuser:mypass".getBytes(Charset.forName("UTF-8"))));
HttpEntity<SomeBody> myRequest = new HttpEntity<>(mybody, headers);
restTemplate.postForEntity(someUrl, myRequest, null);
I'm sure there's some other Base64-library out there if the encoding that ships with the JDK is too verbose for you.
I know that this is an old question, but I was looking for the answer to this myself. You need to add a RestTemplate interceptor when configuring the RestTemplate. An example below in annotation configuration:
@Bean
public RestTemplate restTemplate() {
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(Arrays.asList(
new FormHttpMessageConverter(),
new StringHttpMessageConverter()
));
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("client", "secret"));
return restTemplate;
}
Javadoc for BasicAuthorizationInterceptor.
I was stuck on this for a good few hours. Maybe it will help somebody out in the near future.
I have another solution to set basic authentication for customized rest template.
RestTemplate restTemplate = new RestTemplate();
HttpHost proxy =null;
RequestConfig config=null;
String credentials = this.env.getProperty("uname") + ":" + this.env.getProperty("pwd");
String encodedAuthorization = Base64.getEncoder().encodeToString(credentials.getBytes());
Header header = new BasicHeader(HttpHeaders.AUTHORIZATION, "Basic " + encodedAuthorization);
List<Header> headers = new ArrayList<>();
headers.add(header);
// if we need proxy
if(Boolean.valueOf(env.getProperty("proxyFlag"))){
proxy = new HttpHost(this.env.getProperty("proxyHost"), Integer.parseInt(env.getProperty("proxyPort")), "http");
config= RequestConfig.custom().setProxy(proxy).build();
}else{
config= RequestConfig.custom().build();
}
CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config)
.setDefaultHeaders(headers).build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
restTemplate.setRequestFactory(factory);
return restTemplate;
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:
CommonsClientHttpRequestFactory
integrated with the now end of lifed HttpClient 3.xHttpComponentsClientHttpRequestFactory
(support added in the JIRA SPR-6180)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.