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)
...
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.
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.
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');
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());
}
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.
Il y a une solution
Dans votre code Supprimer ceci
Cela fonctionnera sur ICS
ou Jelly bean
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.
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
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);
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.