Ich kann nicht verstehen, warum Java HttpURLConnection
einer HTTP-Umleitung von einem HTTP zu einer HTTPS-URL nicht folgt. Ich verwende den folgenden Code, um die Seite unter https://httpstat.us/ abzurufen :
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();
}
}
}
Die Ausgabe dieses Programms ist:
Ursprüngliche URL: http://httpstat.us/301 Verbunden mit: http://httpstat.us/301 HTTP-Antwortcode empfangen: 301 Empfangene HTTP-Antwortnachricht: Permanent verschoben
Eine Anfrage an http://httpstat.us/301 gibt die folgende (verkürzte) Antwort zurück (was absolut richtig erscheint!):
HTTP/1.1 301 Moved Permanently
Cache-Control: private
Content-Length: 21
Content-Type: text/plain; charset=utf-8
Location: https://httpstat.us
Leider HttpURLConnection
folgt Java nicht der Weiterleitung!
Beachten Sie, dass , wenn Sie die ursprüngliche URL zu HTTPS ändern ( https://httpstat.us/301 ), Java wird die Umleitung folgen wie erwartet !?
java
redirect
https
httpurlconnection
http-redirect
Shcheklein
quelle
quelle
Antworten:
Weiterleitungen werden nur befolgt, wenn sie dasselbe Protokoll verwenden. (Siehe die
followRedirect()
Methode in der Quelle.) Es gibt keine Möglichkeit, diese Prüfung zu deaktivieren.Obwohl wir wissen, dass es HTTP widerspiegelt, ist HTTPS aus Sicht des HTTP-Protokolls nur ein anderes, völlig anderes, unbekanntes Protokoll. Es wäre unsicher, der Weiterleitung ohne Zustimmung des Benutzers zu folgen.
Angenommen, die Anwendung ist so eingerichtet, dass die Clientauthentifizierung automatisch durchgeführt wird. Der Benutzer erwartet, anonym zu surfen, da er HTTP verwendet. Wenn sein Client jedoch HTTPS folgt, ohne zu fragen, wird seine Identität dem Server mitgeteilt.
quelle
HttpURLConnection
Weiterleitung zu einem anderen Protokoll wird nicht automatisch verfolgt, selbst wenn das Umleitungsflag gesetzt ist.HttpURLConnection von Design wird von HTTP zu HTTPS (oder umgekehrt) nicht automatisch umleiten. Das Folgen der Weiterleitung kann schwerwiegende Sicherheitsfolgen haben. SSL (daher HTTPS) erstellt eine Sitzung, die für den Benutzer eindeutig ist. Diese Sitzung kann für mehrere Anforderungen wiederverwendet werden. Auf diese Weise kann der Server alle Anforderungen einer einzelnen Person verfolgen. Dies ist eine schwache Form der Identität und kann ausgenutzt werden. Außerdem kann der SSL-Handshake das Zertifikat des Clients anfordern. Wenn an den Server gesendet, wird die Identität des Clients an den Server übergeben.
Wie Erickson weist darauf hin, nimmt die Anwendung eingerichtet ist , die Client - Authentifizierung automatisch auszuführen. Der Benutzer erwartet, anonym zu surfen, da er HTTP verwendet. Wenn sein Client jedoch HTTPS folgt, ohne zu fragen, wird seine Identität dem Server mitgeteilt.
Der Programmierer muss zusätzliche Schritte unternehmen, um sicherzustellen, dass Anmeldeinformationen, Clientzertifikate oder SSL-Sitzungs-ID nicht gesendet werden, bevor er von HTTP zu HTTPS umleitet. Standardmäßig werden diese gesendet. Wenn die Umleitung dem Benutzer weh tut, folgen Sie nicht der Umleitung. Aus diesem Grund wird die automatische Umleitung nicht unterstützt.
Nachdem dies verstanden wurde, ist hier der Code, der den Weiterleitungen folgt.
quelle
location = URLDecoder.decode(location...
Teil nur nicht . Dies dekodiert einen funktionierenden codierten relativen Teil (in meinem Fall mit Leerzeichen = +) in einen nicht funktionierenden. Nachdem ich es entfernt hatte, war es für mich in Ordnung.Hat etwas
HttpURLConnection.setFollowRedirects(false)
zufällig angerufen ?Sie können immer anrufen
Wenn Sie sicherstellen möchten, dass Sie den Rest des Verhaltens der App nicht beeinflussen.
quelle
setFollowRedirects
des Typs absolut Recht hatte ,setInstanceFollowRedirects
handelt es sich um eine Instanzmethode , die für den Typ nicht aufgerufen werden kann.Wie von einigen von Ihnen oben erwähnt, funktionieren setFollowRedirect und setInstanceFollowRedirects nur dann automatisch, wenn das umgeleitete Protokoll identisch ist. dh von http zu http und https zu https.
setFolloRedirect befindet sich auf Klassenebene und legt dies für alle Instanzen der URL-Verbindung fest, während setInstanceFollowRedirects nur für eine bestimmte Instanz gilt. Auf diese Weise können wir für verschiedene Instanzen ein unterschiedliches Verhalten haben.
Ich habe hier ein sehr gutes Beispiel gefunden http://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/
quelle
Eine andere Option kann die Verwendung des Apache HttpComponents Client sein :
Beispielcode:
quelle
HTTPUrlConnection ist nicht für die Verarbeitung der Antwort des Objekts verantwortlich. Es ist Leistung wie erwartet, es erfasst den Inhalt der angeforderten URL. Es liegt an Ihnen, dem Benutzer der Funktionalität, die Antwort zu interpretieren. Es ist nicht in der Lage, die Absichten des Entwicklers ohne Spezifikation zu lesen.
quelle