HTTPのリダイレクトとPOSTメソッドの話
社内向けに書こうかと思いましたが、ありえるえりあに書きます。
rfc2616(HTTP/1.1)の話です。
あるWebアプリのログイン画面にユーザIDとパスワードをPOSTした時、そのWebアプリはレスポンスとしてリダイレクト(302)を返す実装になっていました。 事の発端は、WillcomのWX220Jという機種でこのWebアプリにログインすると、自動でリダイレクトしてくれない、という問題でした。
rfc2616には次のように書いてあります。
The action required MAY be carried out by the user agent without interaction with the user if and only if the method used in the second request is GET or HEAD.
要は、リダイレクト時のメソッドがGETもしくはHEADの場合のみ、user agent(Webブラウザと思ってください)は自動でリダイレクトしていい、という話です。それ以外のメソッドの場合は、利用者にリダイレクトしていいかを確認させるのが正しい仕様です。
ちなみに、フォーム認証を行う画面はPOSTメソッドを使うのが鉄則です。なぜならGETメソッドを使うと、パスワードがURLのクエリパラメータに載り次の危険があるからです。
- WebブラウザのURL履歴にパスワード付きのURLが残る
- 途中のプロキシのアクセスログにパスワード付きのURLが残る
後者に関してはPOSTでも残そうと思えば残せます。そもそもHTTPでフォーム認証をするとパスワードが生でネットワークを流れるので、HTTPSを使うべきです(「 パーフェクトJava 」の467ページを参照してください)。
話をrfcに戻します。
HTTP/1.1は今回の問題を解決しています。それが 303 See Other ステータスです。
この前に、前提となる注意事項が 302 Found ステータスの部分に記載されています。
Note: RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request.
元がPOSTメソッドであれば、リダイレクト先にもPOSTでアクセスすることが求められる、ということです。これが、POSTメソッドのリダイレクトを自動で行ってはいけない理由です(今回のようなログイン画面であれば、リダイレクト先にもパスワードをPOSTすることを意味します)。
303 See Other は、「リダイレクト時にHTTPメソッドを変更しない」ルールに例外を認めたステータスです。元がPOSTメソッドでも、リダイレクト先にGETメソッドでアクセスします。この結果、自動リダイレクトが許されます。
なお、303ステータスはHTTP/1.0には存在しません。多くのWebブラウザは302ステータスでも、この動作(元がPOSTメソッドの時でもリダイレクト先にGETでアクセス)をしています。rfc違反ですが仕方ない、とrfc2616でも諦めています。
Spring Frameworkのweb.servlet.view.RedirectView()メソッドは、引数でhttp10Compatible=falseを指定すると、HTTP/1.0では302ステータス、HTTP/1.1では303ステータスのようにリダイレクト時のステータスコードを使い分けてくれるみたいです(Sさん調べ)。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/http-redirect/tbping