Search code examples
springrestful-authenticationhttp-authenticationbasic-authenticationresttemplate

RestTemplate basic or digest Authentication with the current httpclient (4.x)


I'm trying to do Digest mostly (or Basic) Authentication using RestTemplate and httpclient (4.x).

Since I couldn't find any relevant examples of how to actually do this, I have attempted various ways to hook the various httpclient artifacts, with no luck - essentially, no Authentication header is sent at all.

My current implementation is:

DefaultHttpClient newHttpClient = new DefaultHttpClient();
Credentials credentials = new UsernamePasswordCredentials( username, password );
AuthScope authScope = new AuthScope( host, port, AuthScope.ANY_REALM );
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials( authScope, credentials );
newHttpClient.setCredentialsProvider( credentialsProvider );

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory( newHttpClient );
restTemplate.setRequestFactory( requestFactory );

Is there something I'm doing wrong? Is there also a working example for this anywhere? Any help is appreciated. Thanks.


Solution

  • Try implementing your own RequestFactory in order to achieve preemptive authentication.

    public class PreEmptiveAuthHttpRequestFactory extends HttpComponentsClientHttpRequestFactory {
    
    public PreEmptiveAuthHttpRequestFactory(DefaultHttpClient client) {
        super(client);
    }
    
    @Override
    protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
        AuthCache authCache = new BasicAuthCache();
        BasicScheme basicAuth = new BasicScheme();
        HttpHost targetHost = new HttpHost(uri.getHost(), uri.getPort());
        authCache.put(targetHost, basicAuth);
        BasicHttpContext localcontext = new BasicHttpContext();
        localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
    
        return localcontext;
    }
    }
    

    An then just use it:

    HttpComponentsClientHttpRequestFactory requestFactory = new PreEmptiveAuthHttpRequestFactory( newHttpClient );
    

    Hope it helps


    how to set the username and password (Copied from @bifur's comment)

    You can use UserNamePasswordCredentials

    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(getUsername(),getPassword()); 
    client.getCredentialsProvider().setCredentials(new AuthScope(getHost(), getPort(), AuthScope.ANY_REALM), credentials); 
    

    And just use the client in the previous factory

    HttpComponentsClientHttpRequestFactory requestFactory = new PreEmptiveAuthHttpRequestFactory(client);