RestTemplate with Basic Authentication in Spring

Table of Contents

1. Overview

This article shows how to use Springs RestTemplate to consume a RESTful Service secured with Basic Authentication.

Once Basic Authentication is set up for the template, each request will be sent preemptively containing the full credentials necessary to perform the authentication process. The credentials will be encoded and will use the Authorization HTTP Header, in accordance with the specs of the Basic Authentication scheme. An example would look like this:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

2. Setting up the RestTemplate

Bootstraping the RestTemplate into the Spring context can be done by simply declaring a bean for it; however, setting up the RestTemplate with Basic Authentication will require manual intervention, so instead of declaring the bean directly, a Spring FactoryBean will be used for more flexibility. This factory will create and configure the template on initialization:

import org.apache.http.HttpHost;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class RestTemplateFactory implements FactoryBean<RestTemplate>, InitializingBean {
    private RestTemplate restTemplate;

    public RestTemplate getObject() {
        return restTemplate;
    }
    public Class<RestTemplate> getObjectType() {
        return RestTemplate.class;
    }
    public boolean isSingleton() {
        return true;
    }

    public void afterPropertiesSet() {
        HttpHost host = new HttpHost("localhost", 8080, "http");
        restTemplate = new RestTemplate(
          new HttpComponentsClientHttpRequestFactoryBasicAuth(host));
    }
}

The host and port values should be dependent on the environment – allowing the client the flexibility to define one set of values for integration testing and another for production use. The values can be managed by the first class Spring support for properties files.

3. Manual management of the Authorization HTTP header

The process of creating the Authorization header is relatively straightforward for Basic Authentication, so it can pretty much be done manually with a few lines of code:

HttpHeaders createHeaders( String username, String password ){
   return new HttpHeaders(){
      {
         String auth = username + ":" + password;
         byte[] encodedAuth = Base64.encodeBase64( 
            auth.getBytes(Charset.forName("US-ASCII")) );
         String authHeader = "Basic " + new String( encodedAuth );
         set( "Authorization", authHeader );
      }
   };
}

Then, sending a request becomes just as simple:

restTemplate.exchange
 (uri, HttpMethod.POST, new HttpEntity<T>(createHeaders(username, password)), clazz);

4. Automatic management of the Authorization HTTP header

Both Spring 3.0 and 3.1 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)

Let’s start setting things up with HttpClient 4 and Spring 3.1 support.

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:

import java.net.URI;
import org.apache.http.HttpHost;
import org.apache.http.client.AuthCache;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;

public class HttpComponentsClientHttpRequestFactoryBasicAuth 
  extends HttpComponentsClientHttpRequestFactory {

    HttpHost host;

    public HttpComponentsClientHttpRequestFactoryBasicAuth(HttpHost host) {
        super();
        this.host = host;
    }

    protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
        return createHttpContext();
    }
    private HttpContext createHttpContext() {
        // 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
        BasicHttpContext localcontext = new BasicHttpContext();
        localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
        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:

HttpComponentsClientHttpRequestFactory requestFactory =
 (HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory();
DefaultHttpClient httpClient =
 (DefaultHttpClient) requestFactory.getHttpClient();
httpClient.getCredentialsProvider().setCredentials(
 new AuthScope(host, port, AuthScope.ANY_REALM),
  new UsernamePasswordCredentials("name", "pass"));

And the request:

restTemplate.exchange("http://localhost:8080/spring-security-rest-template/api/foos/1", 
  HttpMethod.GET, null, Foo.class);

For an in depth discussion on how to secure the REST Service itself, check out this article.

5. Maven dependencies

The following Maven dependencies are required for the RestTemplate itself and for the HttpClient library:

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>3.2.8.RELEASE</version>
</dependency>

<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.3.2</version>
</dependency>

Optionally, if the HTTP Authorization header is constructed manually, then an additional library is required for the encoding support:

<dependency>
   <groupId>commons-codec</groupId>
   <artifactId>commons-codec</artifactId>
   <version>1.9</version>
</dependency>

6. Conclusion

Although the 3.x branch of development for Apache HttpClient has reached end of life for a while now, and the Spring support for that version has been fully deprecated, much of the information that can be found on RestTemplate and security still doesn’t account for the current HttpClient 4.x releases. This article is an attempt to change that through a detailed, step by step discussion on how to set up Basic Authentication with the RestTemplate and how to use it to consume a secured REST API.

To go beyond the code samples in the article with a production ready implementation of both the consuming side, examined here, but also the actual RESTful Service, check out the REST github project.

I usually post about Security on Google+ - you can follow me there:

Free eBook - REST Services with Spring
Join more than 2,200 engineers!

, , ,

  • Daniel Serodio

    This post was very useful, thanks.

  • baeldung

    Thank – I updated that code sample.

  • jp

    This has been a very helpful page. I respectfully request that you might consider writing up a little about RestTemplate with Digest Authentication using java configuration code (in lieu of xml type annotation).

    Thanks

    • baeldung

      I’m glad the article was helpful – the other article you mentioned is already written – on Digest Auth.
      Thanks. Eugen.

  • Adrian

    thanks – very useful – I used the manual version

  • Abhishek Amte

    Thanks alot. All your tutorials are great and helped me a lot. I have a Spring Web application where I load my jsps and then through ajax calls interact with rest services. I need to secure both of these, but with basic auth there is no logout/custom login for MVC. Can you suggest something

    • http://www.baeldung.com/ Eugen Paraschiv

      It’s allways a little bit tricky to interact with secured REST via Javascript.
      First – one thing to keep in mind is that you’re dealing with two distinct web applications – one is the frontend application (JSPs) and the other is the REST API.
      You can secure the REST API with Basic Authenticaiton (although, I would suggest using Digest over HTTPS), and you can have your standard frontend application secured with standard Spring Security form login.

      Next – you need to consider how to actually call the REST API from your js – and here you also have a few options – you can either use a proxy – and basically proxy all your requests through the frontend application, or you can use a JS library capable of managing Digest authentication, and hit the REST service directly.
      I have done both and, depending on how complex the application is – should work fine.

      Hopefuly that gives you an idea of what your next step may be. Let me know how it goes.

      Cheers,
      Eugen.

      • Abhishek Amte

        Thanks a lot Eugen. Now my configuration is follows – on the server I have two authentications defined in the xml basic for pattern /rest/** and form based for /**. And now I need a way to securely store the username and password in my browser so to send it in my rest calls. Is there a way to do this or should I try something else like token based security instead of form based

        • http://www.baeldung.com/ Eugen Paraschiv

          My suggestion, if this is a reasonable sized application – is to go for a proxy. Client side management of credentials is possible (I had this in the past on simpler projects) – via js libraries (crypto-js among several others) – but it’s somewhat more vulnerable than using the standard cookie based approach with your front end application, and then, from the server side of your front end app, proxy the requests over your REST API (handling the credentials before sending the new request).
          A very good post on the subject, if you want to dig deeper.
          Cheers,
          Eugen.

          • Abhishek Amte

            Thanks alot Eugen. I just checked with my customer and he too is saying no the Client side management. Are any good tutorials or posts available for the proxy based approach. I am new to Spring Security and hence not too familiar with customizing authentication.

          • http://www.baeldung.com/ Eugen Paraschiv

            So – the proxy based approach is not necessarily Spring or Spring Security specific.
            The high level idea is that – you have your front end application secured in the standard way (simplistlically put – form, cookie) and you send all your requests from your JS directly here.
            Then, you re-send the request (proxy) to your REST API with the right type of authentication you require there (for example, if it uses Basic Auth, you would set the Authorization: Basic …. header).

            Now – you can implement this by hand – although be aware that it is doable, but it’s non-trivial, or you can use a library to do it (try different ones until you find something that suits).

            Cheers.
            Eugen.

          • Abhishek Amte

            Thanks. I will start to look into it. I got the high level idea. But I have no idea where to start, should I look into CAS and single sign-on?

          • http://www.baeldung.com/ Eugen Paraschiv

            CAS is a whole different ball of yarn, and from what I understand of your usecase – it’s not required. My suggestion is to start deploying both of your applications and try to communicate between them manually.
            For example – say your js makes a a request to GET /foo – you handle that request in your @Controller layer and you – simply put – you manually forward that to your REST API.
            After you have a good understanding of this type of communication, you can look into not doing the work manually and using a library to proxy your requests – but I would start manually, TDD-ing your way through.
            Cheers.
            Eugen.

          • Abhishek Amte

            So I have to use a RestTemplate and do getforobject,postforobject… and so on? If yes then I have to change my entire Controller Layer

          • http://www.baeldung.com/ Eugen Paraschiv

            You can use the RestTemplate, you can also use the HttpClient. Now – without a proper, in-depth understanding of requirements, constraints, etc, I of course cannot be more specific than this. And, since it looks like your architecture is not yet fully cristilized, my suggestion is to stop coding and starting defining what you need to accomplish – what your frontend app is, what your rest api is, if it makes sense to publish an API or you don’t need to, how they communicate, who handles security, where your js sends request, etc.
            That team excercise should give you a better understanding of responsibilities in your system.
            Hope that makes sense.

            Cheers,

            Eugen.

          • Abhishek Amte

            Yeah Eugen. I understand. I cant thank you enough for helping me out. Thanks a lot.
            Cheers!

          • http://www.baeldung.com/ Eugen Paraschiv

            No worries, hope the project works out well.