web-dev-qa-db-ja.com

HttpURLConnectionはAndroid 2.xでは正常に機能しましたが、4.1では機能しませんでした:認証チャレンジは見つかりませんでした

HttpURLConnectionを使用してURLを含むファイルを取得する一般的なコードがいくつかあります。 Android 1.xと2.xでは問題なく動作しましたが、Android 4.1!

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

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)
...
30
firebear

現在、同じ問題に直面しています。 4.1 Jelly Beanでは、HttpURLConnectionでgetResponseCode()を呼び出すと、IOException "No authentication challenge found"が発生します。

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 = ...を使用している可能性があるという疑いがあります。引用符の欠落がこの問題の原因である可能性があります。それが本当に事実であり、それを機能させることができるかどうか、さらに調査する必要があります。

27
Hendrik

あたり RFC2617

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

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

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

header('WWW-Authenticate: OAuth realm="users"');
header('HTTP/1.1 401 Unauthorized');
26
DanielB6

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

try
{
    responseStream = new BufferedInputStream(connection.getInputStream());
}
catch(IOException e)
{
    responseStream = new BufferedInputStream(connection.getErrorStream());
}
6
petrnohejl

見出し

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

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);

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

1
Amit

1つの解決策があります

あなたのコードでこれを削除してください

HttpConnection.setDoOutput(true);

ICSまたはJelly beanで動作します

0
Trikaldarshi

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

0
joepetrakovich

基本認証を使用し、setDoOutput(true)を呼び出さない場合でも、この問題が発生していました。

これが解決策です:

AndroidでのHTTP基本認証の問題

0
Nick

正しく動作するためにCookieを必要とするWebサービスで同様の問題が発生しました。どうやらJelly Beanはデフォルトでは(以前のバージョンとは異なり)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);
0
James

サーバーがError 401 - Not Authorisedを返しているかどうかを確認します。 Androidコードはその応答を見て、認証の詳細を提供することを意図していたと信じています。私の場合、サーバーに間違ったトークンを提供していただけです。

0