HttpServletRequest#getRemoteAddr()とIPv6
仕事場のPCで普通に動いているWebアプリケーションの認証クラスが、何故か自宅のPCでは例外を吐くので調べることにしたのだが、表題のメソッドの戻り値を判断している部分に問題があることが判明した。問題のクラスはIPアドレスのデリミタがカンマピリオド"."であることを前提にしてアドレスの検査を行っていたのである。
結論から書くが、Windows Vista上で表題のメソッドを実行した場合、戻り値はIPv4形式ではなく、IPv6形式(128bit、コロン":"デリミタ)でアドレス表現された文字列が戻るので注意が必要だ。(使用したJVMはver1.6.0-b105、Tomcat5.5.20使用時)
一番解りやすい例で言うと、ホストの設定がlocalhostであれば同サーバから自らにアクセスした場合、戻り値はループバックアドレスなので
127.0.0.1
を期待するだろうが、実際に戻るのは
0:0:0:0:0:0:0:1
となるのである。
ちなみにこの結果は別にJavaだけのことではなく、同様にコマンドプロンプトからlocalhostにpingを打っても同じ結果である。
C:\Users\Kazz>ping localhost Kazz.pc [::1]に ping を送信しています ::1 から 32 バイトのデータ:
- 1 からの応答: 時間 <1ms
- 1 からの応答: 時間 <1ms
- 1 からの応答: 時間 <1ms
- 1 からの応答: 時間 <1ms
IPv6への移行が騒がれてから随分と経つが、世の中のアプリケーションではIPアドレスの文字列表現の区切り文字がカンマピリオド"."であることを前提にしたロジックがまだあるのが現状だろう。
今まではさほど気にしていなかったが、こうして身近で体験すると怖さを実感する。