30 votes

HttpURLConnection fonctionnait bien dans Android 2.x mais PAS dans 4.1: Aucun défi d'authentification trouvé

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

J'ai cherché sur le Web mais j'ai trouvé 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)
...
 

27voto

Hendrik Points 5399

Je suis actuellement confronté au même problème. Sur 4.1 Jelly Bean-je recevoir une IOException "Aucune authentification défis trouvé" lors de l'appel de getResponseCode() sur le HttpURLConnection.

J'ai cherché en ligne pour voir ce qui a changé dans le code source Android et constaté ce qui suit: 4.0.4 (de travail): 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 la section 4.1 JB la méthode getAuthorizationCredentials() renvoie la IOException. Il analyse le défi têtes qu'il trouve dans la réponse à l'aide de HeaderParser.parseChallenges(..), si le code de réponse est de 401 407. Si la Liste retourné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 cause exactement que la Liste soit vide, mais qui ont le soupçon que notre serveur peut utiliser realm=... au lieu de realm="..." dans le défi d'en-tête. Manquant entre guillemets peut être la cause de ce problème. Nous devons examiner de plus si c'est effectivement le cas et si nous pouvons le faire fonctionner.

26voto

DanielB6 Points 445

Par RFC2617:

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

Dans Android, la HttpURLConnection getResponseCode() méthode lève java.io.IOException: No authentication challenges found lorsque le serveur renvoie un 401 Unauthorized ou 407 Proxy Authentication Required code de statut de sans-tête WWW-Authenticate ensemble.

Si vous possédez l'API côté serveur, vous pouvez y remédier en ajoutant le nécessaire-tête WWW-Authenticate lorsque vous revenez 401 407. Dans mon cas, j'ai corrigé ça en PHP comme suit:

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

6voto

petrnohejl Points 2483

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

1voto

Amit Points 237

Rubrique

J'ai réglé 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(nouveau AuthScope(null, -1), la nouvelle UsernamePasswordCredentials(nom d'utilisateur,userPass));
HttpGet demande = new HttpGet();
demande.addHeader("Accepter", "application/xml");
demande.setURI(new URI(service));
HttpResponse response = client.execute(demande);

vous avez obtenu la bonne réponse que vous avez besoin.

0voto

Matthew Blackford Points 1429

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 juste le mauvais jeton à mon serveur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X