No puedo entender por qué Java HttpURLConnection
no sigue un redireccionamiento HTTP de un HTTP a una URL HTTPS. Utilizo el siguiente código para obtener la página en https://httpstat.us/ :
import java.net.URL;
import java.net.HttpURLConnection;
import java.io.InputStream;
public class Tester {
public static void main(String argv[]) throws Exception{
InputStream is = null;
try {
String httpUrl = "http://httpstat.us/301";
URL resourceUrl = new URL(httpUrl);
HttpURLConnection conn = (HttpURLConnection)resourceUrl.openConnection();
conn.setConnectTimeout(15000);
conn.setReadTimeout(15000);
conn.connect();
is = conn.getInputStream();
System.out.println("Original URL: "+httpUrl);
System.out.println("Connected to: "+conn.getURL());
System.out.println("HTTP response code received: "+conn.getResponseCode());
System.out.println("HTTP response message received: "+conn.getResponseMessage());
} finally {
if (is != null) is.close();
}
}
}
El resultado de este programa es:
URL original: http://httpstat.us/301 Conectado a: http://httpstat.us/301 Código de respuesta HTTP recibido: 301 Mensaje de respuesta HTTP recibido: Movido permanentemente
Una solicitud a http://httpstat.us/301 devuelve la siguiente respuesta (abreviada) (¡que parece absolutamente correcta!):
HTTP/1.1 301 Moved Permanently
Cache-Control: private
Content-Length: 21
Content-Type: text/plain; charset=utf-8
Location: https://httpstat.us
Desafortunadamente, Java HttpURLConnection
no sigue la redirección.
Tenga en cuenta que si cambia la dirección URL original a HTTPS ( https://httpstat.us/301 ), Java va a seguir la redirección como se esperaba !?
java
redirect
https
httpurlconnection
http-redirect
Shcheklein
fuente
fuente
Respuestas:
Los redireccionamientos se siguen solo si usan el mismo protocolo. (Consulte el
followRedirect()
método en la fuente). No hay forma de deshabilitar esta verificación.Aunque sabemos que refleja HTTP, desde el punto de vista del protocolo HTTP, HTTPS es solo otro protocolo desconocido completamente diferente. No sería seguro seguir la redirección sin la aprobación del usuario.
Por ejemplo, suponga que la aplicación está configurada para realizar la autenticación del cliente automáticamente. El usuario espera navegar de forma anónima porque usa HTTP. Pero si su cliente sigue HTTPS sin preguntar, su identidad se revela al servidor.
fuente
HttpURLConnection
seguirá automáticamente las redirecciones a un protocolo diferente, incluso si se establece la marca de redirección.HttpURLConnection por diseño no redirigirá automáticamente de HTTP a HTTPS (o viceversa). Seguir la redirección puede tener graves consecuencias para la seguridad. SSL (de ahí HTTPS) crea una sesión que es única para el usuario. Esta sesión se puede reutilizar para múltiples solicitudes. Por lo tanto, el servidor puede rastrear todas las solicitudes realizadas por una sola persona. Ésta es una forma débil de identidad y es explotable. Además, el protocolo de enlace SSL puede solicitar el certificado del cliente. Si se envía al servidor, la identidad del cliente se le da al servidor.
Como señala Erickson , suponga que la aplicación está configurada para realizar la autenticación del cliente automáticamente. El usuario espera navegar de forma anónima porque usa HTTP. Pero si su cliente sigue HTTPS sin preguntar, su identidad se revela al servidor.
El programador debe tomar medidas adicionales para asegurarse de que las credenciales, los certificados de cliente o la identificación de sesión SSL no se envíen antes de redirigir de HTTP a HTTPS. El valor predeterminado es enviarlos. Si la redirección perjudica al usuario, no siga la redirección. Por eso no se admite el redireccionamiento automático.
Con eso entendido, aquí está el código que seguirá las redirecciones.
fuente
location = URLDecoder.decode(location...
parte. Esto decodifica una parte relativa codificada de trabajo (con espacio = + en mi caso) en una que no funciona. Después de que lo quité, estaba bien para mí.¿Ha llamado algo
HttpURLConnection.setFollowRedirects(false)
por casualidad?Siempre puedes llamar
si desea asegurarse de no afectar el resto del comportamiento de la aplicación.
fuente
setFollowRedirects
al tipo,setInstanceFollowRedirects
es un método de instancia y no se puede llamar al tipo.Como algunos de ustedes mencionaron anteriormente, setFollowRedirect y setInstanceFollowRedirects solo funcionan automáticamente cuando el protocolo redirigido es el mismo. es decir, de http a http y de https a https.
setFolloRedirect está en el nivel de clase y establece esto para todas las instancias de la conexión de URL, mientras que setInstanceFollowRedirects es solo para una instancia determinada. De esta forma podemos tener un comportamiento diferente para diferentes instancias.
Encontré un muy buen ejemplo aquí http://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/
fuente
Otra opción puede ser utilizar Apache HttpComponents Client :
Código de muestra:
fuente
HTTPUrlConnection no es responsable de manejar la respuesta del objeto. Tiene el rendimiento esperado, captura el contenido de la URL solicitada. Depende de usted, el usuario de la funcionalidad, interpretar la respuesta. No es capaz de leer las intenciones del desarrollador sin especificación.
fuente