基本上我需要做的是执行摘要式身份验证。我尝试的第一件事是可用的官方示例here。 但是当我尝试执行它时(通过一些小的更改,Post而不是Get方法)我得到了一个
org.apache.http.auth.MalformedChallengeException: missing nonce in challange
at org.apache.http.impl.auth.DigestScheme.processChallenge(DigestScheme.java:132)
如果失败,我尝试使用:
DefaultHttpClient client = new DefaultHttpClient();
client.getCredentialsProvider().setCredentials(new AuthScope(null, -1, null), new UsernamePasswordCredentials("<username>", "<password>"));
HttpPost post = new HttpPost(URI.create("http://<someaddress>"));
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("domain", "<username>"));
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
DigestScheme digestAuth = new DigestScheme();
digestAuth.overrideParamter("algorithm", "MD5");
digestAuth.overrideParamter("realm", "http://<someaddress>");
digestAuth.overrideParamter("nonce", Long.toString(new Random().nextLong(), 36));
digestAuth.overrideParamter("qop", "auth");
digestAuth.overrideParamter("nc", "0");
digestAuth.overrideParamter("cnonce", DigestScheme.createCnonce());
Header auth = digestAuth.authenticate(new
UsernamePasswordCredentials("<username>", "<password>"), post);
System.out.println(auth.getName());
System.out.println(auth.getValue());
post.setHeader(auth);
HttpResponse ret = client.execute(post);
ByteArrayOutputStream v2 = new ByteArrayOutputStream();
ret.getEntity().writeTo(v2);
System.out.println("----------------------------------------");
System.out.println(v2.toString());
System.out.println("----------------------------------------");
System.out.println(ret.getStatusLine().getReasonPhrase());
System.out.println(ret.getStatusLine().getStatusCode());
起初我只覆盖了“realm”和“nonce”DigestScheme参数。但事实证明,在服务器上运行的PHP脚本需要所有其他参数,但无论我是否指定它们,当我调用其authenticate()方法时,DigestScheme不会在Authorization RequestPreperty中生成它们。 PHP脚本返回HTTP响应代码200,其中包含PHP脚本需要cnonce,nc和qop参数的消息。
我两天都在苦苦挣扎,没有运气。根据一切我认为问题的原因是PHP脚本。在我看来,当应用尝试未经授权访问时,它不会发送挑战。
任何想法?
编辑: 还有一件事,我尝试过连接cURL,它可以工作。
答案 0 :(得分:3)
我在验证代码后设法使用digestScheme
进行摘要登录。
digestAuth.processChallenge(null);
强制解释先前的输入参数。 null参数是一个标头,基于发送的标头(如果有)。
现在使用qop/nc
并且digestScheme根据需要工作。
在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();
}
答案 1 :(得分:2)
此代码段对我有用。您必须通过查看从主机获得的401响应标头来提供您可以获得的领域。
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);
答案 2 :(得分:2)
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.12'
compile group: 'commons-io', name: 'commons-io', version: '2.6'
等级:
media_item.setText(" ") # set the item with a dummy string
media_item.setFont(QFont('Verdana', 180)) # make the font big so it covers the whole widget
答案 3 :(得分:-2)
你们这么复杂。如果您阅读apache httpclient的文档,那将非常简单。
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();
}
}