Apache Http Digest Authentication using Java

16,516

Solution 1

This code works for me pretty well:

protected static void downloadDigest(URL url, FileOutputStream fos)
  throws IOException {
  HttpHost targetHost = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
  CloseableHttpClient httpClient = HttpClients.createDefault();
  HttpClientContext context = HttpClientContext.create();

  String credential = url.getUserInfo();
  if (credential != null) {
    String user = credential.split(":")[0];
    String password = credential.split(":")[1];

    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(AuthScope.ANY,
      new UsernamePasswordCredentials(user, password));
    AuthCache authCache = new BasicAuthCache();
    DigestScheme digestScheme = new DigestScheme();
    authCache.put(targetHost, digestScheme);

    context.setCredentialsProvider(credsProvider);
    context.setAuthCache(authCache);
  }

  HttpGet httpget = new HttpGet(url.getPath());

  CloseableHttpResponse response = httpClient.execute(targetHost, httpget, context);

  try {
    ReadableByteChannel rbc = Channels.newChannel(response.getEntity().getContent());
    fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
  } finally {
    response.close();
  }
}

Solution 2

Tipp: do not use HTTP Digest :) It is not secure at all. Over HTTPS it has not point.

If you must, below is a code that works with parsing the WWW-Authenticate header.

This is tested with the following dependency (i use gradle):

compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'

The code:

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class DigestExample {

  private final static String uri = "http://my.digest.based.auth.url.com";
  private static HttpHost target;

  public static void main(String[] args) throws IOException {    

    setup();
    if (target == null) {
      System.out.println("Setup was unsuccesfull");
      return;
    }
    Header challengeHeader = getAuthChallengeHeader();
    if (challengeHeader == null) {
      System.out.println("Setup was unsuccesfull");
      return;
    }

    // NOTE: challenge is reused for subsequent HTTP GET calls (typo corrected)
    getWithDigestAuth(challengeHeader, "/", "/schema");

  }

  private static void setup() throws MalformedURLException {
    URL url = new URL(uri);
    target = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
  }

  private static Header getAuthChallengeHeader() {
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
      CloseableHttpResponse response = httpClient.execute(new HttpGet(uri));
      return response.getFirstHeader("WWW-Authenticate");
    } catch (IOException e) {
      e.printStackTrace();
      return null;
    }
  }

  private static void getWithDigestAuth(Header challengeHeader, String... requests)
      throws IOException {

    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(
        new AuthScope(target.getHostName(), target.getPort()),
        new UsernamePasswordCredentials("user", "pass"));

    try (CloseableHttpClient httpclient = HttpClients.custom()
        .setDefaultCredentialsProvider(credsProvider)
        .build()) {

      // Create AuthCache instance
      AuthCache authCache = new BasicAuthCache();
      // Generate DIGEST scheme object, initialize it and add it to the local
      // auth cache
      DigestScheme digestAuth = new DigestScheme();
      digestAuth.processChallenge(challengeHeader);
      authCache.put(target, digestAuth);

      // Add AuthCache to the execution context
      HttpClientContext localContext = HttpClientContext.create();
      localContext.setAuthCache(authCache);

      for (String request : requests) {
        System.out.println("Executing request to target " + target + request);
        try (CloseableHttpResponse response = httpclient
            .execute(target, new HttpGet(request), localContext)) {
          System.out.println("----------------------------------------");
          System.out.println(response.getStatusLine());
          System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
          System.out.println("Error while executing HTTP GET request");
          e.printStackTrace();
        }
      }
    } catch (MalformedChallengeException e) {
      e.printStackTrace();
    }
  }
}

Solution 3

try this code from apache httpClient 4.3.3

final HttpHost targetHost = new HttpHost("localhost", 8080, "http");
    final CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(AuthScope.ANY,
            new UsernamePasswordCredentials(user, password));

    final AuthCache authCache = new BasicAuthCache();
    DigestScheme digestAuth = new DigestScheme();
    digestAuth.overrideParamter("realm", "some-realm");
    digestAuth.overrideParamter("nonce", "whatever");
    authCache.put(targetHost, digestAuth);

    // Add AuthCache to the execution context
    HttpClientContext context = HttpClientContext.create();
    context.setAuthCache(authCache);
HttpGet httpget = new HttpGet("/");
CloseableHttpResponse response = httpclient.execute(targetHost , httpget, context );

Please can you give me the site which requires HTTP digest authentication?

Share:
16,516

Related videos on Youtube

user2351234
Author by

user2351234

Updated on June 04, 2022

Comments

  • user2351234
    user2351234 almost 2 years

    I am currently working on a Java project and I can't get the http digest authentication working. I tried using the Apache website, but it didn't help. I have a site that requires HTTP digest authentication.

            DefaultHttpClient httpclient = new DefaultHttpClient();
            String hostUrl = "http://somewebsite.com";
            String postUrl = "http://somewebsite.com/request";
            HttpPost httpPost = new HttpPost(postUrl);
            String username = "hello";
            String password = "world";
            HttpHost targetHost = new HttpHost(hostUrl);
    
            httpclient.getCredentialsProvider().setCredentials(
                    new AuthScope(hostUrl, AuthScope.ANY_PORT),
                    new UsernamePasswordCredentials(username, password));
    
            AuthCache authCache = new BasicAuthCache();
    
            DigestScheme digestAuth = new DigestScheme();
    
            digestAuth.overrideParamter("realm", "some realm");
    
            digestAuth.overrideParamter("nonce", "whatever");
            authCache.put(targetHost, digestAuth);
    
            BasicHttpContext localcontext = new BasicHttpContext();
            localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
    
            // List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            // nvps.add(new BasicNameValuePair("username", "[email protected]"));
            // nvps.add(new BasicNameValuePair("password", "example"));
            // httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            HttpResponse response2 = httpclient.execute(httpPost);
    
    • Michel Ayres
      Michel Ayres about 10 years
      any solution for that?
  • Nirmal Mangal
    Nirmal Mangal over 9 years
    did you find any online webservice to test your stuff?
  • jamiltz
    jamiltz about 9 years
    I use httpbin.org. There is a digest auth endpoint to test. But I still get a 401 back using the code above. Is this snippet working for anyone using Digest Auth?