1. ホーム
  2. java

[解決済み] HTTPURLConnection が HTTP から HTTPS へのリダイレクトに従わない

2022-10-23 06:56:54

質問

私は、なぜJavaの HttpURLConnection がHTTPからHTTPSのURLへのHTTPリダイレクトに従わない理由がわかりません。私は以下のコードを使って、ページを 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();
        }
    }
}

このプログラムの出力は

元のURL: http://httpstat.us/301
接続先: http://httpstat.us/301
受け取ったHTTPレスポンスコード 301
受信した HTTP レスポンスメッセージ 永久に移動しました

へのリクエストは http://httpstat.us/301 にリクエストすると、次のような(短縮された)レスポンスが返されます(これは絶対に正しいと思われます!)。

HTTP/1.1 301 Moved Permanently
Cache-Control: private
Content-Length: 21
Content-Type: text/plain; charset=utf-8
Location: https://httpstat.us

残念ながら、Javaの HttpURLConnection はリダイレクトに従わないのです!

元の URL を HTTPS に変更した場合は注意が必要です ( https://httpstat.us/301 ) に変更すると、Java は期待通りにリダイレクトに従います!?

どのように解決するのですか?

リダイレクトは、同じプロトコルを使用している場合のみ従います。(参照 followRedirect() メソッド をソースに追加してください)。このチェックを無効にする方法はありません。

HTTP をミラーリングしているとわかっていても、HTTP プロトコルの観点からは、HTTPS は他のまったく異なる未知のプロトコルに過ぎないのです。ユーザーの承認なしにリダイレクトを実行するのは安全ではありません。

たとえば、アプリケーションがクライアント認証を自動的に実行するように設定されているとします。ユーザーは HTTP を使用しているため、匿名でネットサーフィンすることを期待しています。しかし、クライアントが何も聞かずに HTTPS に従った場合、彼の身元がサーバーに明らかになります。