Gee*_*eek 23 java authentication android httpurlconnection ioexception
我是android的新手,这是我在android上的第一个项目.我在"认证"问题上苦苦挣扎了一天多.我尝试了几个选项,但没有一个可行.
基本上,我想调用REST API并获得响应.我确信API中没有问题,因为我在另一个iOS应用程序中使用相同的API.
我传递授权标题但仍然显示身份验证未找到消息.我发现与stackoverflow相关的问题很少,但是其中一些没有用,有些对我没有意义.
我得到状态代码401.我知道这意味着要么没有传递身份验证,要么传递,那么它们就错了.在这里,我确信我传递的是正确的.
以下是我的代码:
try {
url = new URL(baseUrl);
}
catch (MalformedURLException me) {
Log.e(TAG, "URL could not be parsed. URL : " + baseUrl + ". Line : " + getLineNumber(), me);
me.printStackTrace();
}
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod(method);
urlConnection.setConnectTimeout(TIMEOUT * 1000);
urlConnection.setChunkedStreamingMode(0);
// Set HTTP headers
String authString = "username:password";
String base64Auth = Base64.encodeToString(authString.getBytes(), Base64.DEFAULT);
urlConnection.setRequestProperty("Authorization", "Basic " + base64Auth);
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestProperty("Content-type", "application/json");
if (method.equals("POST") || method.equals("PUT")) {
// Set to true when posting data
urlConnection.setDoOutput(true);
// Write data to post to connection output stream
OutputStream out = urlConnection.getOutputStream();
out.write(postParameters.getBytes("UTF-8"));
}
try {
// Get response
in = new BufferedInputStream(urlConnection.getInputStream());
}
catch (IOException e) {
Log.e(TAG, "Exception in getting connection input stream. in : " + in);
e.printStackTrace();
}
// Read the input stream that has response
statusCode = urlConnection.getResponseCode();
Log.d(TAG, "Status code : " + statusCode);
}
catch (ProtocolException pe) {
pe.printStackTrace();
}
catch (IllegalStateException ie) {
ie.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
urlConnection.disconnect();
}
Run Code Online (Sandbox Code Playgroud)
看一下logcat的截图:

任何帮助,将不胜感激.谢谢.
pat*_*ckf 49
发生此错误的原因是服务器发送401(未授权)但未提供WWW-Authenticate标题,这是对客户端下一步操作的提示.的WWW-Authenticate报头告诉客户端,需要哪种类型的认证的(或者基本或摘要).这在无头http客户端中可能不是很有用,但这就是HTTP 1.1 RFC的定义方式.发生此错误是因为lib尝试解析WWW-Authenticate标头但不能.
来自RFC:
(...)响应必须包含WWW-Authenticate头字段(第14.47节),其中包含适用于所请求资源的质询.(...)
如果您可以更改服务器可能的解决方案:
WWW-Authenticate: Basic realm="fake".这仅仅是一种解决方法而不是一种解决方案,但它应该可以工作并且http客户端很满意(请参阅此处讨论您可以在标题中添加的内容).但请注意,某些http客户端可能会自动重试请求,从而导致多个请求(例如,过于频繁地增加错误的登录计数).这是在iOS http客户端上观察到的.WWW-Authenticate: xBasic realm="fake".重要的是realm必须包括在内.403而不是401.它的语义不一样,通常在使用登录401时是正确的响应(请参阅此处进行详细讨论),但在兼容性方面更安全.如果您无法更改服务器,可能的解决方案:
正如@ErikZ在他的帖子中写道,你可以使用try&catch
HttpURLConnection connection = ...;
try {
// Will throw IOException if server responds with 401.
connection.getResponseCode();
} catch (IOException e) {
// Will return 401, because now connection has the correct internal state.
int responsecode = connection.getResponseCode();
}
Run Code Online (Sandbox Code Playgroud)使用不同的http客户端,如OkHttp
您在哪个版本的 Android 上进行测试?
在 Gingerbread 的一些开发工作中,我遇到了 Android 身份验证器的困难(我不知道它在 Android 的更高版本上的行为是否有所不同)。我使用 Fiddler2 检查我的应用程序和服务器之间的 HTTP 流量,发现身份验证器没有为每个 HTTP 请求发送身份验证字符串。我需要它。
相反,我采取了这样的方法:
urlConnection.setRequestProperty("Authorization", "Basic " + Base64.encodeToString("userid:pwd".getBytes(), Base64.NO_WRAP ));
Run Code Online (Sandbox Code Playgroud)
这是我的代码的剪切和粘贴。请注意,urlConnection 是一个 HttpURLConnection 对象。
| 归档时间: |
|
| 查看次数: |
31337 次 |
| 最近记录: |