使用HttpURLConnection在Android中进行摘要式身份验证

Spr*_*bua 5 java android httpurlconnection digest-authentication

正如问题所说,我正在尝试在android中进行摘要式身份验证.
到目前为止,我已经使用了DefaultHttpClient它和它的身份验证方法(使用UsernamePasswordCredentials等等),但是自Android 5以来它已经被弃用,并且将在Android 6中删除.
所以我即将切换DefaultHttpClientHttpUrlConnection.
我现在想实现摘要式身份验证,这应该工作作为解释非常简单的在这里:

Authenticator.setDefault(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username, password);
    }
});
Run Code Online (Sandbox Code Playgroud)

但是getPasswordAuthentication从来没有因为某些原因而被召唤.
在我搜索这个问题的过程中,我找到了不同的帖子,说HttpUrlConnection在android中不支持摘要认证,但这些帖子是从2010年到2012年,所以我不确定这是否仍然是真的.我们HttpUrlConnection还在桌面java应用程序中使用摘要式身份验证,它可以在其中运行.

我还发现了一些帖子,谈论着OkHttp.OkHttp似乎Android被引擎使用(更具体地说HttpUrlConnectionImpl).但这HttpUrlConnectionImpl有点奇怪,它甚至没有在Eclipse类型层次结构中显示,我无法调试它.它也应该是一个com.squareup.okhttp.internal.huc.HttpUrlConnectionImpl,而在android中它是一个com.android.okhttp.internal.http.HttpUrlConnectionImpl.

所以我只是无法HttpUrlConnection在android中进行摘要认证.
没有外部库,谁能告诉我如何做到这一点?

编辑:
服务器要求摘要验证:

WWW-Authenticate: Digest realm="Realm Name",domain="/domain",nonce="nonce",algorithm=MD5,qop="auth"
Run Code Online (Sandbox Code Playgroud)

所以基本身份验证不应该工作,因为服务器要求摘要.

Nap*_*ppy 6

答案是,这HttpUrlConnection不支持摘要.

因此,您必须自己实施RFC2617.

您可以使用以下代码作为基线实现:Android的HTTP Digest Auth.

涉及的步骤(参见RFC2617以供参考):

  • 如果您收到401响应,请遍历所有WWW-Authenticate标头并解析它们:
    • 检查算法是MD5还是未定义,(可选择选择authqop选项),否则忽略挑战并转到下一个标题.
    • 使用获取凭据Authenticator.requestPasswordAuthentication.
    • 使用用户名,域和密码计算H(A1).
    • 存储规范的根URL,域,HA1,用户名,nonce(+可选算法,opaque和客户端选择的qop选项,如果存在).
    • 重试请求.
  • 在每个请求上,迭代您拥有规范根URL存储的会话信息的所有领域:
    • 使用请求方法和路径计算H(A2).
    • 使用HA1,nonce(+任选nc,cnonce,qop)和HA2计算H(A3).
    • 构建并添加Authorization标题到您的HttpUrlConnection.
  • 实现某种会话修剪.

通过使用Authenticator,您可以确保,只要HttpUrlConnection本机支持摘要,您的代码就不再被使用(因为您首先不会收到401).

这只是关于如何实现它的快速摘要,供您了解.

如果你想更进一步,你可能也希望实现SHA256:RFC7616


use*_*876 5

HttpUrlConnection不支持摘要认证是正确的。如果您的客户端必须使用 Digest 进行身份验证,您有几个选择:

  • 编写您自己的 HTTP 摘要实现。如果您知道需要向哪些服务器进行身份验证并且可以忽略摘要规范中不需要的部分,那么这可能是一个不错的选择。这是一个实施摘要子集的示例:https : //gist.github.com/slightfoot/5624590
  • 使用外部库bare-bones-digest,这是 Android 的 Digest 库。您可以使用它来解析 Digest 挑战并生成对它们的响应。它支持常见的摘要用例和一些很少使用的用例,并且可以在HttpURLConnection.
  • 使用OkHttp连同okhttp消化,这是增加了HTTP摘要支持OkHttp插件。使用 OkHttp 支持 Digest 很容易,只需添加okhttp-digest为身份验证器,您将获得透明的 Http 摘要支持。如果您已经使用 OkHttp 或者可以切换到它,这可能是一个有吸引力的选择。
  • 使用HttpClient支持 Digest的 Apache 。这个问题明确指出这HttpClient不是一个选项,所以我主要是为了完成而包含它。Google 不推荐使用HttpClient并且已弃用它。