Apache Httpclient Digest Authentication

Apache HTTPClient DigestAuth doesn't forward opaque value from Challenge

Finally fixed by overriding the Authorize header explicitly, instead of relying on the internals of HttpClient to do it automatically:

package [...];

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.io.IOUtils;
import org.apache.http.*;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.*;
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.*;
import org.testng.Assert;

public class DigestTest {

private static final String URL
= "https://...";

private static final String PASSWORD = ...;

private static final String USER = ...;

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

new DigestTest().run();
}

public void run() throws Exception {

HttpGet httpget = new HttpGet(URL);

HttpHost target
= new HttpHost(httpget.getURI().getHost(), 443, "https");
CredentialsProvider credsProvider = new BasicCredentialsProvider();

UsernamePasswordCredentials credentials
= new UsernamePasswordCredentials(USER, PASSWORD);
credsProvider.setCredentials(
new AuthScope(target.getHostName(), target.getPort()),
credentials);

CookieStore cookieStore = new BasicCookieStore();

CloseableHttpClient httpclient
= HttpClients.custom().setDefaultCookieStore(cookieStore)
.setDefaultCredentialsProvider(credsProvider).build();

try {

DigestScheme digestAuth = new DigestScheme();

digestAuth.overrideParamter("qop", "auth");
digestAuth.overrideParamter("nc", "0");
digestAuth.overrideParamter("cnonce", DigestScheme.createCnonce());

AuthCache authCache = new BasicAuthCache();
authCache.put(target, digestAuth);

HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);

CloseableHttpResponse response;

response = httpclient.execute(target, httpget, localContext);
Map<String, String> wwwAuth = Arrays
.stream(response.getHeaders("WWW-Authenticate")[0]
.getElements())
.collect(Collectors.toMap(HeaderElement::getName,
HeaderElement::getValue));

// the first call ALWAYS fails with a 401
Assert.assertEquals(response.getStatusLine().getStatusCode(), 401);

digestAuth.overrideParamter("opaque", wwwAuth.get("opaque"));
digestAuth.overrideParamter("nonce", wwwAuth.get("nonce"));
digestAuth.overrideParamter("realm", wwwAuth.get("Digest realm"));
Header authenticate = digestAuth.authenticate(credentials, httpget,
localContext);
httpget.addHeader(authenticate);

response = httpclient.execute(target, httpget, localContext);

// the 2nd call is the real deal
Assert.assertEquals(response.getStatusLine().getStatusCode(), 200);

System.out.println(IOUtils
.toString(response.getEntity().getContent(), "utf-8"));

} finally {
httpclient.close();
}
}

}

Apache HttpClient Digest Authentication Failed

The following code worked for me

import java.util.Random;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;

/**
* A simple example that uses HttpClient to execute an HTTP request against a
* target site that requires user authentication.
*/
public class RestClient {

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

HttpHost targetHost = new HttpHost("localhost", 8001, "http");
DefaultHttpClient httpclient = new DefaultHttpClient();

final String userName = "admin";
final String password = "password";

httpclient.getCredentialsProvider().setCredentials(
new AuthScope("localhost", 8001),
new UsernamePasswordCredentials(userName, password));

// 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();
// Suppose we already know the realm name
digestAuth.overrideParamter("realm", "some realm");
// Suppose we already know the expected nonce value
digestAuth.overrideParamter("nonce", "whatever");
authCache.put(targetHost, digestAuth);

// Add AuthCache to the execution context
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);

HttpGet httpget = new HttpGet("http://localhost:8001/rest/test");

try {
HttpResponse response = httpclient.execute(targetHost, httpget, localcontext);
HttpEntity entity = response.getEntity();

System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
EntityUtils.consume(entity);
} finally {
httpclient.getConnectionManager().shutdown();
}
}
}


Related Topics



Leave a reply



Submit