基本上,我需要执行摘要身份验证。我尝试的第一件事是可用的官方示例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 ”和“即席” DigestScheme参数。但是事实证明,在服务器上运行的PHP脚本需要所有其他参数,但是无论我是否指定它们,当我调用DigestScheme的authenticate()方法时,DigestScheme都不会在Authorization RequestPreperty中生成它们。并且PHP脚本返回HTTP响应代码200,并带有一条消息,表明PHP脚本需要cnonce,nc和qop参数。

我已经为此挣扎了两天,没有运气。基于一切,我认为问题的原因是PHP脚本。在我看来,当应用程序尝试未经授权访问它时,它不会发出挑战。

有任何想法吗?

编辑:
还有一件事,我尝试使用cURL进行连接,并且可以正常工作。

最佳答案

验证代码后,我设法使用digestScheme进行了摘要登录。

digestAuth.processChallenge(null);

强制解释先前的输入参数。 null参数是一个 header ,基于发送的 header (如果有)。

现在使用了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();
}

07-27 16:01