问题
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", "shirwa99@gmail.com"));
// nvps.add(new BasicNameValuePair("password", "example"));
// httpPost.setEntity(new UrlEncodedFormEntity(nvps));
HttpResponse response2 = httpclient.execute(httpPost);
回答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();
}
}
回答2:
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?
回答3:
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();
}
}
}
回答4:
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();
}
}
来源:https://stackoverflow.com/questions/17599339/apache-http-digest-authentication-using-java