por - HttpURLConnection funcionó bien en Android 2.x pero NO en 4.1: no se encontraron desafíos de autenticación
httpurlconnection post android (9)
Tengo algunos códigos típicos que utilizan HttpURLConnection para obtener un archivo con una URL. Funcionaron bien en Android 1.xy 2.x. ¡Pero falló en Android 4.1!
Busqué en la web pero encontré poca información similar. ¿Alguien podría ayudar a investigar este problema?
private String mURLStr;
private HttpURLConnection mHttpConnection;
...
url = new URL(mURLStr);
...
mHttpConnection = (HttpURLConnection) url.openConnection();
mHttpConnection.setDoOutput(true);
mHttpConnection.setRequestMethod("GET");
...
InputStream is = mHttpConnection.getInputStream();
El método getInputStream arroja una excepción:
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)
...
Actualmente estoy enfrentando el mismo problema. En 4.1 Jelly Bean, recibo una excepción IOException "No se encontraron desafíos de autenticación" al llamar a getResponseCode () en HttpURLConnection.
He buscado en línea para ver qué ha cambiado en el código fuente de Android y encontré lo siguiente: 4.0.4 (en funcionamiento): https://bitbucket.org/seandroid/libcore/src/7ecbe081ec95/luni/src/main/java/libcore/net/http/HttpURLConnectionImpl.java 4.1.1 (no funciona): https://bitbucket.org/seandroid/libcore/src/6b27266a2856/luni/src/main/java/libcore/net/http/HttpURLConnectionImpl.java
Como se puede ver en 4.1 JB, el método getAuthorizationCredentials () arroja la IOException. Analiza los encabezados de desafío que encuentra en la respuesta usando HeaderParser.parseChallenges (..), si el código de respuesta es 401 o 407. Si la lista devuelta está vacía, se lanza la excepción.
Actualmente estamos investigando qué causa exactamente que la Lista esté vacía, pero tenemos la sospecha de que nuestro servidor podría usar el dominio = ... en lugar del reino = "..." en el encabezado del desafío. Las comillas que faltan pueden ser la causa de este problema. Tenemos que investigar más a fondo si ese es realmente el caso y si podemos hacerlo funcionar.
Compruebe si su servidor está devolviendo un Error 401 - Not Authorised
. Creo que el código de Android ve esa respuesta y cree que fue para proporcionar detalles de autenticación. En mi caso, solo estaba proporcionando el token equivocado a mi servidor.
Cuando utilizamos la autenticación básica y no llamamos a setDoOutput (verdadero), todavía tenemos este problema:
Aquí está la solución:
Problema de autenticación básica de HTTP en Android Jelly Bean 4.1 utilizando HttpURLConnection
Hay una solución
En tu código Eliminar esto
HttpConnection.setDoOutput (verdadero);
Funcionará en ICS
o Jelly Bean
Me encontré con un problema similar con un servicio web que requería cookies para funcionar correctamente. Aparentemente, Jelly Bean no crea automáticamente una tienda de cookies por defecto (a diferencia de las versiones anteriores), por lo que el servicio no pudo encontrar mi sesión y arrojó un 401 cada vez que intenté acceder a él. Agregar las siguientes líneas de código a la inicialización de mi aplicación solucionó el problema:
// 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);
Por RFC2617 :
El mensaje de respuesta 401 (no autorizado) es utilizado por un servidor de origen para impugnar la autorización de un agente de usuario. Esta respuesta DEBE incluir un campo de encabezado WWW-Authenticate que contenga al menos un desafío aplicable al recurso solicitado.
En Android, el método HttpURLConnection getResponseCode () arroja java.io.IOException: No authentication challenges found
cuando el servidor devuelve un código de estado 401 Unauthorized
o 407 Proxy Authentication Required
sin el conjunto de encabezado WWW-Authenticate.
Si posee la API del lado del servidor, puede solucionarlo agregando el encabezado WWW-Authenticate requerido cuando devuelva 401 o 407. En mi caso, lo arreglé en PHP de la siguiente manera:
header(''WWW-Authenticate: OAuth realm="users"'');
header(''HTTP/1.1 401 Unauthorized'');
Título
He solucionado el problema del Jelly Bean. Utilice el siguiente código para el escenario anterior
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);
obtuviste la respuesta adecuada como lo necesitabas.
Tengo el mismo problema. Encontré esta solución, pero no funciona en Android 2. En Jelly Bean, funciona bien. Simplemente use getErrorStream () en lugar de getInputStream ().
try
{
responseStream = new BufferedInputStream(connection.getInputStream());
}
catch(IOException e)
{
responseStream = new BufferedInputStream(connection.getErrorStream());
}
Una solución que utilicé para esto (estoy usando la biblioteca Volley de Android) fue utilizar la biblioteca OkHttp de Square . Su implementación maneja correctamente este problema y devolverá el 401 como se esperaba.