Basic Authentication with RestTemplate

Spring Rest Templates are very good way of writing REST clients. By default they work with basic HTTP so if we need to use Basic Authorization we would need to init the rest template with custom HttpClient. This way the Rest Template will automatically use Basic Auth and append to the HTTP headers "Authorization: Basic BASE64ENCODED_USER_PASS".


HttpClient client = new HttpClient();
UsernamePasswordCredentials credentials =
new UsernamePasswordCredentials("USERNAME","PASS");
client.getState().setCredentials(
  new AuthScope("www.example.com", 9090, AuthScope.ANY_REALM),
  credentials);
CommonsClientHttpRequestFactory commons =
     new CommonsClientHttpRequestFactory(client);

RestTemplate template = new RestTemplate(commons);
SomeObject result = template.getForObject(
     "http://www.example.com:9090/",SomeObject.class
 );



In EE application this would probably be managed by DI framework like Spring Core and only initialized once since  RestTemplate is stateless.


Links:
HTTP Basic Auth
Spring Rest Templates
Spring Rest Templates JavaDoc
Apache HTTP components

3 comments:

cra5h said...

In Spring 3.1, this works well:

SimpleClientHttpRequestFactory s = new SimpleClientHttpRequestFactory() {
@Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
super.prepareConnection(connection, httpMethod);

//Basic Authentication for Police API
String authorisation = "user" + ":" + "pass";
byte[] encodedAuthorisation = Base64.encode(authorisation.getBytes());
connection.setRequestProperty("Authorization", "Basic " + new String(encodedAuthorisation));
}
};

RestTemplate authorisedRestTemplate = new RestTemplate(s);

Please note that this will do the authentication with every request and won't store it for further request!

Mite Mitreski said...

This looks great, its more nicely done than my solution but I had to support Spring 3.0.6 and I'm not sure if this works well there.

Mikael Bergström said...

Hello,
thanks for nice blogg.

I tested a variant using the Restemplate.exchange() and used the HttpEntity parameter to set HttpHeaders including the "Authorization" header.

E.g:
HttpHeaders httpHeaders = new HttpHeaders();
//Basic Authentication
String authorisation = "username" + ":" + "passwd";
byte[] encodedAuthorisation = Base64.encode(authorisation.getBytes());
httpHeaders.add("Authorization", "Basic " + new String(encodedAuthorisation));

new RestTemplate().exchange("https://url...", HttpMethod.GET, new HttpEntity<>(httpHeaders), Map.class);

(The type inside the HttpEntity<> should be Map if anyone would like to test the variant)