30

HttpURLConnection を使用して URL を持つファイルを取得する典型的なコードがいくつかあります。Android 1.x および 2.x では問題なく動作しました。しかし、Android 4.1 で失敗しました。

Webで検索しましたが、同様の情報はほとんど見つかりませんでした。誰かこの問題の調査を手伝ってくれませんか?

private String mURLStr; 
private HttpURLConnection mHttpConnection;

...

url = new URL(mURLStr);

...

mHttpConnection = (HttpURLConnection) url.openConnection();
mHttpConnection.setDoOutput(true);
mHttpConnection.setRequestMethod("GET");

...

InputStream is = mHttpConnection.getInputStream();

getInputStream メソッドは例外をスローします。

08-01 15:56:48.856: W/System.err(13613): java.io.IOException: No authentication challenges found
08-01 15:56:48.856: W/System.err(13613):      at libcore.net.http.HttpURLConnectionImpl.getAuthorizationCredentials(HttpURLConnectionImpl.java:427)
08-01 15:56:48.866: W/System.err(13613):      at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java:407)
08-01 15:56:48.866: W/System.err(13613):      at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java:356)
08-01 15:56:48.866: W/System.err(13613):      at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:292)
08-01 15:56:48.866: W/System.err(13613):      at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
...
4

9 に答える 9

27

私は現在同じ問題に直面しています。4.1 Jelly Beanでは、HttpURLConnectionでgetResponseCode()を呼び出すと、「認証チャレンジが見つかりません」というIOExceptionが発生します。

オンラインでAndroidソースコードの変更点を確認したところ、次のことがわかりました。4.0.4(動作中):https ://bitbucket.org/seandroid/libcore/src/7ecbe081ec95/luni/src/main/java/ libcore / net / http / HttpURLConnectionImpl.java 4.1.1(機能していません):https ://bitbucket.org/seandroid/libcore/src/6b27266a2856/luni/src/main/java/libcore/net/http/HttpURLConnectionImpl.java

4.1 JBでわかるように、メソッドgetAuthorizationCredentials()はIOExceptionをスローします。応答コードが401または407の場合、HeaderParser.parseChallenges(..)を使用して、応答で見つかったチャレンジヘッダーを解析します。返されたリストが空の場合、例外がスローされます。

https://bitbucket.org/seandroid/libcore/src/6b27266a2856/luni/src/main/java/libcore/net/http/HeaderParser.java

現在、そのリストが空になる原因を正確に調査していますが、サーバーがチャレンジヘッダーでrealm="..."ではなくrealm=...を使用している可能性があると思われます。引用符がないことがこの問題の原因である可能性があります。それが実際に当てはまるかどうか、そしてそれを機能させることができるかどうかをさらに調査する必要があります。

于 2012-09-28T16:15:46.343 に答える
26

RFC2617ごと:

401 (Unauthorized) 応答メッセージは、オリジン サーバーがユーザー エージェントの承認に挑戦するために使用されます。この応答には、要求されたリソースに適用可能な少なくとも 1 つのチャレンジを含む WWW-Authenticate ヘッダー フィールドを含める必要があります。

Android では、サーバーが WWW-Authenticate ヘッダーを設定せずにまたはステータス コードを返すと、 HttpURLConnection getResponseCode()メソッドがスローされます。java.io.IOException: No authentication challenges found401 Unauthorized407 Proxy Authentication Required

サーバー側 API を所有している場合は、401 または 407 を返すときに必要な WWW-Authenticate ヘッダーを追加することで修正できます。私の場合は、次のように PHP で修正しました。

header('WWW-Authenticate: OAuth realm="users"');
header('HTTP/1.1 401 Unauthorized');
于 2013-02-26T01:24:40.320 に答える
6

私も同じ問題を抱えてる。この回避策を見つけましたが、Android 2 では機能しません。Jelly Bean では正常に機能します。getInputStream() の代わりに getErrorStream() を使用してください。

try
{
    responseStream = new BufferedInputStream(connection.getInputStream());
}
catch(IOException e)
{
    responseStream = new BufferedInputStream(connection.getErrorStream());
}
于 2012-11-29T11:21:58.857 に答える
1

見出し

ジェリービーンの問題を修正しました。上記のシナリオには以下のコードを使用してください

DefaultHttpClient client = new DefaultHttpClient();
client.getCredentialsProvider().setCredentials(new AuthScope(null, -1), new UsernamePasswordCredentials(userName,userPass));
HttpGet request = new HttpGet();
request.addHeader("Accept", "application/xml");
request.setURI(new URI(service));
HttpResponse response = client.execute(request);

必要に応じて適切な応答が得られました。

于 2013-02-14T06:34:28.390 に答える
0

正しく動作するためにCookieを必要とするWebサービスで同様の問題が発生しました。どうやらJellyBeanは(以前のバージョンとは異なり)デフォルトでCookieストアを自動的に作成しないため、サービスはセッションを見つけることができず、アクセスしようとするたびに401をスローしました。アプリケーションの初期化に次のコード行を追加すると、問題が修正されました。

// enable VM-wide cookie support for HttpUrlConnection
// see http://developer.android.com/reference/java/net/HttpURLConnection.html for details
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
于 2013-01-04T22:21:55.833 に答える
0

基本認証を使用し、setDoOutput(true) を呼び出さない場合、まだこの問題がありました。

解決策は次のとおりです。

HttpURLConnection を使用した Android Jelly Bean 4.1 での HTTP 基本認証の問題

于 2013-01-27T20:00:02.403 に答える
0

1つのソリューションがあります

コードでこれを削除します

HttpConnection.setDoOutput(true);

ICSまたは_Jelly Bean

于 2013-07-16T07:51:27.180 に答える
0

サーバーがError 401 - Not Authorised. 私は、Android コードがその応答を見て、認証の詳細を提供するためのものであると信じています。私の場合、間違ったトークンをサーバーに提供していました。

于 2013-05-07T10:55:20.200 に答える
0

これに使用した解決策 (Android の Volley ライブラリを使用しています) は、 Square の OkHttp ライブラリを使用することでした。彼らの実装はこの問題を正しく処理し、期待どおりに 401 を返します。

于 2013-08-16T22:59:02.873 に答える