RestTemplate with Basic Authentication using interceptors

01.10.2013

Why this post?

You might ask why I do another post about this topic and not just entered the right search term in Google. The answer is simple - I did exactly this and found only solutions I didn't like. I wanted some transparent way to add a basic-auth header and use my RestTemplate as I always did.

That's what this post is all about.

Not much to say about - only the code!

I simply wrote an interceptor, called BasicAuthInterceptor, which adds the necessary headers for authentication.

import java.io.IOException;
import java.nio.charset.Charset;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

public class BasicAuthInterceptor implements ClientHttpRequestInterceptor {

    private static final Logger logger = LoggerFactory.getLogger( BasicAuthInterceptor.class );

    private final String username;
    private final String password;

    public BasicAuthInterceptor( String username, String password ) {
        this.username = username;
        this.password = password;
    }

    @Override
    public ClientHttpResponse intercept( HttpRequest request, byte[] body, ClientHttpRequestExecution execution ) throws IOException {

        //Build the auth-header
        final String auth = username + ":" + password;
        final byte[] encodedAuth = Base64.encodeBase64( auth.getBytes( Charset.forName( "US-ASCII" ) ) );
        final String authHeader = "Basic " + new String( encodedAuth );

        //Add the auth-header
        request.getHeaders().add( "Authorization", authHeader );

        logger.info( "Added Basic Authentication Header: user -> {}, password -> {}", username, mask( password ) );

        return execution.execute( request, body );
    }

    private String mask( String toMask ) {
        return toMask.replaceAll( ".", "*" );
    }
}

And here is how to use it in conjuction with your RestTemplate.

import java.util.ArrayList;
import java.util.List;

import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;

public class SimpleClient {

    public static void main( String[] args ) {

        //Get a new Rest-Template
        final RestTemplate template = new RestTemplate();

        //Create and initialize the interceptor
        final List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
        interceptors.add( new BasicAuthInterceptor( "admin", "secret" ) );
        template.setInterceptors( interceptors );

        //Do your request as normal...
        final String helloResponse = template.getForObject( "http://localhost:8080/hello", String.class ); 

        System.out.println(helloResponse);
    }
}

The Maven dependencies

The following dependencies are required for the code to work. I used slf4j for logging - but you can use whatever you want to.

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

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