web-dev-qa-db-fra.com

HttpURLConnection a bien fonctionné sous Android 2.x mais PAS dans la version 4.1: aucun problème d'authentification trouvé

J'ai quelques codes typiques qui utilisaient HttpURLConnection pour obtenir un fichier avec une URL . Ils fonctionnaient bien sous Android 1.x et 2.x. Mais échoué dans Android 4.1!

J'ai cherché sur le Web, mais je n'ai trouvé que peu d'informations similaires .. Quelqu'un pourrait-il aider à enquêter sur ce problème?

private String mURLStr; 
private HttpURLConnection mHttpConnection;

...

url = new URL(mURLStr);

...

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

...

InputStream is = mHttpConnection.getInputStream();

La méthode getInputStream lève une exception:

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

Je suis actuellement confronté au même problème. Sur 4.1 Jelly Bean, je reçois une exception IOException "Aucun défi d'authentification trouvé" lorsque j'appelle getResponseCode () sur HttpURLConnection.

J'ai effectué une recherche en ligne pour voir ce qui a changé dans le code source Android et trouvé les éléments suivants: 4.0.4 (en état de marche): https://bitbucket.org/seandroid/libcore/src/7ecbe081ec95/luni/src /main/Java/libcore/net/http/HttpURLConnectionImpl.Java 4.1.1 (ne fonctionne pas): https://bitbucket.org/seandroid/libcore/src/6b27266a2856/luni/src/main /Java/libcore/net/http/HttpURLConnectionImpl.Java

Comme on peut le voir dans 4.1 JB, la méthode getAuthorizationCredentials () lève l’exception IOException. Il analyse les en-têtes de défi qu'il trouve dans la réponse à l'aide de HeaderParser.parseChallenges (..), si le code de réponse est 401 ou 407. Si la liste renvoyée est vide, l'exception est levée.

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

Nous étudions actuellement ce qui fait que cette liste est vide, mais nous soupçonnons que notre serveur pourrait utiliser le domaine = ... au lieu de domaine = "..." dans l'en-tête du challenge. Les guillemets manquants peuvent être la cause de ce problème. Nous devons examiner plus avant si c'est effectivement le cas et si nous pouvons le faire fonctionner.

27
Hendrik

Per RFC2617 :

Le message de réponse 401 (non autorisé) est utilisé par un serveur Origin contester l'autorisation d'un agent utilisateur. Cette réponse DOIT inclure un champ d’en-tête WWW-Authenticate contenant au moins un défi applicable à la ressource demandée.

Dans Android, la méthode HttpURLConnection getResponseCode () renvoie Java.io.IOException: No authentication challenges found lorsque le serveur renvoie un code d'état 401 Unauthorized ou 407 Proxy Authentication Required sans le jeu d'en-tête WWW-Authenticate.

Si vous possédez l'API côté serveur, vous pouvez y remédier en ajoutant l'en-tête WWW-Authenticate requis lorsque vous renvoyez 401 ou 407. Dans mon cas, je l'ai corrigé dans PHP comme suit:

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

J'ai le même problème. J'ai trouvé cette solution de contournement, mais cela ne fonctionne pas sur Android 2. Sur Jelly Bean, cela fonctionne bien. Utilisez simplement getErrorStream () au lieu de getInputStream ().

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

Titre

J'ai résolu le problème de la fève à la gelée. Veuillez utiliser le code ci-dessous pour le scénario ci-dessus. 

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

vous avez la bonne réponse selon vos besoins.

1
Amit

Il y a une solution 

Dans votre code Supprimer ceci 

HttpConnection.setDoOutput (true);

Cela fonctionnera sur ICS ou Jelly bean

0
Trikaldarshi

Une solution que j'ai utilisée pour cela (j'utilise la bibliothèque Volley d'Android) était d'utiliser La bibliothèque OkHttp de Square . Leur implémentation gère correctement ce problème et renverra le 401 comme prévu.

0
joepetrakovich

Lorsque nous utilisions l'authentification de base sans appeler setDoOutput (true), nous avions toujours ce problème:

Voici la solution:

Problème d'authentification HTTP basique sur Android Jelly Bean 4.1 à l'aide de HttpURLConnection

0
Nick

J'ai rencontré un problème similaire avec un service Web qui nécessitait le bon fonctionnement des cookies. Apparemment, Jelly Bean ne crée pas automatiquement de magasin de cookies (contrairement aux versions précédentes), le service n'a donc pas pu trouver ma session et a lancé un 401 à chaque fois que j'essayais d'y accéder. L'ajout des lignes de code suivantes à l'initialisation de mon application a résolu le problème:

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

Vérifiez si votre serveur renvoie un Error 401 - Not Authorised. Je crois que le code Android voit cette réponse et pense qu'il était destiné à fournir des détails d'authentification. Dans mon cas, je fournissais simplement le mauvais jeton à mon serveur.

0