使用 HttpURLConnection 的 Android Jelly Bean 4.1 上的 HTTP 基本身份验证问题
Posted
技术标签:
【中文标题】使用 HttpURLConnection 的 Android Jelly Bean 4.1 上的 HTTP 基本身份验证问题【英文标题】:HTTP Basic Authentication issue on Android Jelly Bean 4.1 using HttpURLConnection 【发布时间】:2013-01-11 02:07:56 【问题描述】:我们正在使用 HTTP 基本身份验证向 Web 服务器发出基于 HttpURLConnection 的请求。 代码在 android 版本 2.x、3.x.、4.0.x 上运行良好 现在使用 Jelly Bean 和 v4.1.x 身份验证失败,LogCat 中显示以下消息:
01-27 10:54:18.886: ...::doReadRawData(731): An exception occured while reading data from remote host. httpURLConn.responseCode = 401 / httpURLConn.responseMessage = UNAUTHORIZED
01-27 10:54:18.886: ...::doReadRawData(731): java.io.IOException: No authentication challenges found
我们在 Android 文档中用于 HttpURLConnection 的身份验证代码:
private void doAuthorize()
Authenticator.setDefault(new Authenticator()
protected PasswordAuthentication getPasswordAuthentication()
return new PasswordAuthentication(USER, PASSWORD.toCharArray());
);
经过进一步调查和故障排除,我们发现在 4.1 Jelly Bean 中没有调用此代码!
Android Jelly Bean 4.1 中基本身份验证的解决方法或正确方法是什么?
有人在这个相关主题的 Android 源代码中发现了不同,我认为我们遇到的问题与这种不同有关:HttpURLConnection worked fine in Android 2.x but NOT in 4.1: No authentication challenges found
【问题讨论】:
【参考方案1】:我们能够通过以下新方法解决 Jelly Bean 不调用 Authenticator 的 getPasswordAuthentication() 的问题:
@TargetApi(Build.VERSION_CODES.FROYO)
private void setJellyBeanAuth(HttpURLConnection httpConn)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
byte[] auth = (USER + ":" + PASSWORD).getBytes();
String basic = Base64.encodeToString(auth, Base64.NO_WRAP);
httpConn.setRequestProperty("Authorization", "Basic " + basic);
然后在打开连接后调用这个函数:
httpURLConn = (HttpURLConnection) url.openConnection();
setJellyBeanAuth(httpURLConn);
仅需要用于 Froyo 注释的 @TargetApi,因为我们仍然支持 API 7,而在 API 8 中添加了 Base64
【讨论】:
当我尝试做一个多部分时,这个标题技巧对我不起作用【参考方案2】:对于 Android 的 httpURLConnection 的 401 UNAUTHORIZED 响应,您的服务器必须发回这样的身份验证标头... WWW-Authenticate: Bogus realm="blahblah", comment="使用表单登录" 根据https://www.rfc-editor.org/rfc/rfc2616 搜索“10.4.2 401 未授权”
【讨论】:
这是真正的解决方案。 Android HttpURLConnectionImpl 依赖服务端提供客户端进行身份验证的方式。以上是关于使用 HttpURLConnection 的 Android Jelly Bean 4.1 上的 HTTP 基本身份验证问题的主要内容,如果未能解决你的问题,请参考以下文章
android中的HttpUrlConnection的使用之二