Apache HttpClient 摘要式身份验证
基本上我需要做的是执行摘要身份验证。我尝试的第一件事是可用的官方示例 此处。 但是当我尝试执行它时(进行一些小的更改,Post 而不是 Get 方法),我得到一个
org.apache.http.auth.MalformedChallengeException: missing nonce in challange
at org.apache.http.impl.auth.DigestScheme.processChallenge(DigestScheme.java:132)
When this failed I try using:
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 连接并且它有效。
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 changes, Post instead of the the Get method) I get a
org.apache.http.auth.MalformedChallengeException: missing nonce in challange
at org.apache.http.impl.auth.DigestScheme.processChallenge(DigestScheme.java:132)
When this failed I tried using:
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());
At first I have only overridden "realm" and "nonce" DigestScheme parameters. But it turned out that PHP script running on the server requires all other params, but no matter if I specify them or not DigestScheme doesn't generate them in the Authorization RequestPreperty when I call its authenticate() method. And PHP script returns HTTP response code 200 with a message that PHP script requires cnonce, nc and qop parameters.
I've been struggling with this for two days, and no luck. Based on everything I think that the cause of the problem is the PHP script. It looks to me that it doesn't send a challenge when app tries to access it unauthorized.
Any ideas anyone?
Edit:
One more thing, I've tried connecting with cURL and it works.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这个代码片段对我有用。您必须提供通过查看从主机获得的 401 响应标头可以获得的领域。
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.
验证代码后,我设法使用
digestScheme
进行摘要登录。强制解释先前的输入参数。 null 参数是一个标头,基于发送的标头(如果有)。
现在使用了qop/nc并且digestScheme按要求工作。
在安卓上运行
I managed to do a Digest login using
digestScheme
after verifying the code.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
摇篮:
Gradle :
你们把事情搞得这么复杂。如果你阅读 apache httpclient 的文档,那会非常简单。
You guys make it so complicated. If you read the documentation of apache httpclient, it would be super easy.