Basically what I need to do is to perform digest authentication. First thing I tried is the official example available here. But when I try to execute it(with some small ch
This code snippet worked for me. You have to provide the realm which you can get by looking at the 401 response header you get from the host.
val credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(user, password));
val authCache = new BasicAuthCache();
val digestScheme = new DigestScheme();
digestScheme.overrideParamter("realm", "**Name of the Realm**");
// Nonce value
digestScheme.overrideParamter("nonce", "whatever");
authCache.put(targetHost, digestScheme);
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
val httpget = new HttpGet(url);
val response = httpClient.execute(targetHost, httpget, context);
private static byte[] downloadFileWithDigitAuth(String url, String username, String password) {
byte[] bytes = null;
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpGet httpGet = new HttpGet(url);
HttpContext httpContext = new BasicHttpContext();
CloseableHttpResponse httpResponse = null;
try {
httpResponse = httpClient.execute(httpGet, httpContext);
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
Header authHeader = httpResponse.getFirstHeader(AUTH.WWW_AUTH);
DigestScheme digestScheme = new DigestScheme();
/*
override values if need
No need override values such as nonce, opaque, they are generated by server side
*/
digestScheme.overrideParamter("realm", "User Login Required !!");
digestScheme.processChallenge(authHeader);
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
httpGet.addHeader(digestScheme.authenticate(creds, httpGet, httpContext));
httpResponse.close();
httpResponse = httpClient.execute(httpGet);
}
bytes = IOUtils.toByteArray(httpResponse.getEntity().getContent());
} catch (IOException | MalformedChallengeException | AuthenticationException e) {
e.printStackTrace();
}
finally {
if (httpResponse != null) {
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bytes;
}
Gradle :
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.12'
compile group: 'commons-io', name: 'commons-io', version: '2.6'
You guys make it so complicated. If you read the documentation of apache httpclient, it would be super easy.
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();
}
}
I managed to do a Digest login using digestScheme
after verifying the code.
digestAuth.processChallenge(null);
Forces the previous input parameters to be interpreted. The null parameter is a header, based on the header sent, if any.
Now qop/nc
is used and digestScheme works as required.
Running it on android
digestAuth.overrideParamter("algorithm", "MD5");
digestAuth.overrideParamter("realm", serverRealm);
digestAuth.overrideParamter("nonce", Long.toString(new Random().nextLong(), 36));
digestAuth.overrideParamter("qop", "auth");// not effective
digestAuth.overrideParamter("nc",""+sequence);//nt effective
digestAuth.overrideParamter("cnonce", DigestScheme.createCnonce());
digestAuth.overrideParamter("opaque","ba897c2f0f3de9c6f52d");
String err;
try
{
digestAuth.processChallenge(null);
//force qop in use chalange on return header ????!!!!
}
catch (Exception e)
{
err=e.getLocalizedMessage();
}