it-swarm.com.de

HttpURLConnection funktionierte gut in Android 2.x, aber NICHT in 4.1: Keine Authentifizierungsherausforderungen gefunden

Ich habe einige typische Codes, die HttpURLConnection verwendet haben, um eine Datei mit einer URL zu erhalten. Sie funktionierten gut in Android 1.x und 2.x. Aber in Android 4.1 gescheitert!

Ich habe im Internet gesucht, aber wenig ähnliche Informationen gefunden. Würde bitte jemand helfen, dieses Problem zu untersuchen?

private String mURLStr; 
private HttpURLConnection mHttpConnection;

...

url = new URL(mURLStr);

...

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

...

InputStream is = mHttpConnection.getInputStream();

Die getInputStream-Methode löst eine Ausnahme aus:

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

Ich bin derzeit mit dem gleichen Problem konfrontiert. Bei 4.1 Jelly Bean erhalte ich eine IOException "Keine Authentifizierungsherausforderungen gefunden", wenn getResponseCode () für die HttpURLConnection aufgerufen wird.

Ich habe online nach den Änderungen im Android-Quellcode gesucht und Folgendes gefunden: 4.0.4 (funktioniert): https://bitbucket.org/seandroid/libcore/src/7ecbe081ec95/luni /src/main/Java/libcore/net/http/HttpURLConnectionImpl.Java 4.1.1 (funktioniert nicht): https://bitbucket.org/seandroid/libcore/src/6b27266a2856/luni /src/main/Java/libcore/net/http/HttpURLConnectionImpl.Java

Wie man in 4.1 JB sehen kann, löst die Methode getAuthorizationCredentials () die IOException aus. Die in der Antwort gefundenen Challenge-Header werden mit HeaderParser.parseChallenges (..) analysiert, wenn der Antwortcode 401 oder 407 lautet. Wenn die zurückgegebene Liste leer ist, wird die Ausnahme ausgelöst.

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

Wir untersuchen derzeit, was genau diese Liste leer macht, haben aber den Verdacht, dass unser Server im Challenge-Header realm = ... anstelle von realm = "..." verwendet. Fehlende Anführungszeichen können die Ursache für dieses Problem sein. Wir müssen weiter untersuchen, ob dies tatsächlich der Fall ist und ob wir es schaffen können.

27
Hendrik

Per RFC2617 :

Die Antwortnachricht 401 (nicht autorisiert) wird von einem Origin-Server Verwendet, um die Autorisierung eines Benutzeragenten abzufragen. Diese Antwort MUSS Ein WWW-Authenticate-Headerfeld enthalten, das mindestens eine -Aufforderung enthält, die auf die angeforderte Ressource anwendbar ist.

In Android gibt die HttpURLConnection getResponseCode () -Methode Java.io.IOException: No authentication challenges found aus, wenn der Server einen 401 Unauthorized- oder 407 Proxy Authentication Required-Statuscode ohne den WWW-Authenticate-Header-Satz zurückgibt.

Wenn Sie die serverseitige API besitzen, können Sie sie beheben, indem Sie den erforderlichen WWW-Authenticate-Header hinzufügen, wenn Sie 401 oder 407 zurückgeben. In meinem Fall habe ich ihn in PHP wie folgt behoben:

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

Ich habe das gleiche Problem. Ich habe diese Problemumgehung gefunden, funktioniert aber nicht auf Android 2. Bei Jelly Bean funktioniert es einwandfrei. Verwenden Sie einfach getErrorStream () anstelle von getInputStream ().

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

Überschrift

Ich habe das Problem für die Jelly Bean behoben. Bitte verwenden Sie den Code unten für das obige Szenario 

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

sie haben die richtige Antwort bekommen, als Sie brauchten.

1
Amit

Es gibt eine Lösung 

Entfernen Sie dies in Ihrem Code 

HttpConnection.setDoOutput (true);

Es funktioniert mit ICS oder Jelly bean

0
Trikaldarshi

Eine Lösung, die ich dafür verwendete (ich verwende die Volley-Bibliothek von Android) war die Verwendung von Square's OkHttp-Bibliothek . Ihre Implementierung behandelt dieses Problem korrekt und gibt die 401 wie erwartet zurück.

0
joepetrakovich

Bei Verwendung der Standardauthentifizierung und ohne Aufruf von setDoOutput (true) hatten wir immer noch dieses Problem:

Hier ist die Lösung:

HTTP-Basisauthentifizierungsproblem bei Android Jelly Bean 4.1 mit HttpURLConnection

0
Nick

Ich hatte ein ähnliches Problem mit einem Webdienst, für den Cookies erforderlich waren, um ordnungsgemäß zu funktionieren. Anscheinend erstellt Jelly Bean (im Gegensatz zu früheren Versionen) standardmäßig nicht automatisch einen Cookie-Speicher. Daher konnte der Dienst meine Sitzung nicht finden und warf jedes Mal, wenn ich darauf zugegriffen habe, eine 401. Durch das Hinzufügen der folgenden Codezeilen zu meiner Anwendungsinitialisierung wurde das Problem behoben:

// 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

Prüfen Sie, ob Ihr Server einen Error 401 - Not Authorised zurückgibt. Ich glaube, der Android-Code sieht diese Antwort und glaubt, dass er Authentifizierungsdetails bereitstellen sollte. In meinem Fall habe ich meinem Server nur das falsche Token zur Verfügung gestellt.

0