Apache Http Digest Authentication using Java

心已入冬 提交于 2019-12-06 05:05:28

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();
  }
}

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?

Sobvan

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();
    }
  }
}

Try this code from Apache :

   public static void main(String[] args) throws Exception {
            HttpClient client = new HttpClient();
            client.getState().setCredentials(
                new AuthScope("myhost", 80, "myrealm"),
                new UsernamePasswordCredentials("username", "password"));
            // Suppose the site supports several authetication schemes: NTLM and Basic
            // Basic authetication is considered inherently insecure. Hence, NTLM authentication
            // is used per default

            // This is to make HttpClient pick the Basic authentication scheme over NTLM & Digest
            List authPrefs = new ArrayList(3);
            authPrefs.add(AuthPolicy.BASIC);
            authPrefs.add(AuthPolicy.NTLM);
            authPrefs.add(AuthPolicy.DIGEST);
            client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authrefs);

            GetMethod httpget = new GetMethod("http://myhost/protected/auth-required.html");

            try {
                int status = client.executeMethod(httpget);
                // print the status and response
                System.out.println(httpget.getStatusLine());
                System.out.println(httpget.getResponseBodyAsString());
            } finally {
                // release any connection resources used by the method
                httpget.releaseConnection();
            }            
        }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!