WebLogicでのサーブレットリダイレクションプロトコル
Web開発において、ブラウザは特定のHTTPステータスコードに対して「Location」ヘッダーを含むレスポンスを受け取ると、自動的にリダイレクトします。自動リダイレクトをトリガーするコードは3で始まります。Java Servlet API、すなわちjavax.servlet.http.HttpServletResponse.sendRedirect(String)を使用すると、
通常は302になります。
サーブレットアプリケーションをTomcatなどからWebLogicに移行すると、「Location」ヘッダーが絶対URLに評価されてしまうという奇妙な現象に遭遇することがあります。残念ながら、これはSSLを終端し、HTTPポートでWebLogicに接続するリバースプロキシとうまく連携しない可能性があります。
WebLogicの絶対URLリダイレクト
WebLogic上のサーブレットは、HTTPSリバースプロキシ経由で接続しているにもかかわらず(転送されたヘッダーに関わらず)、HTTPプロトコルのLocationにリダイレクトすることがあります。
https://example.com/app/foo にPOSTを送信するとします。これはリバースプロキシの背後でsendRedirect("bar")を呼び出すWebLogicサーブレットです。
# リクエストヘッダー(簡潔さのため、無関係なヘッダーは省略)
POST /app/foo HTTP/1.1
Host: example.com
Origin: https://example.com
Referer: https://example.com/bar
リバースプロキシからのリクエスト:
POST /app/foo HTTP/1.1
Host: [example.com]
X-forwarded-host: [example.com]
Upgrade-insecure-requests: [1]
X-forwarded-server: [example.com]
X-forwarded-for: [192.168.0.100]
X-forwarded-proto: [https]
X-forwarded-ssl: [on]
転送されたヘッダーが存在するにもかかわらず、WebLogicはHTTPSではなくHTTPのロケーションで応答します:
HTTP/1.1 302 Moved Temporarily
Location: http://example.com/app/bar
混合コンテンツリダイレクトの解決策
これにはさまざまな解決策があります:
- プロキシでレスポンスヘッダーを書き換える。
- レスポンスヘッダーを書き換えるカスタムフィルターを実装する。
- WebLogicコンソールで「WebLogic Plugin Enabled」オプションをオンにし、プロキシで「WL-Proxy-SSL: ON」リクエストヘッダーを追加する。
- WebLogicコンソールにWLフロントエンドホストとポートを追加する。
しかし、提供されているサーブレットライブラリの内容を調べた結果、 最も安全で簡単な解決策は、リダイレクション中の絶対URL評価を無効にすることだと気づきました。
これをデバッグするために、
sendRedirect()メソッドにブレークポイントを置き、任意のgetClass().getProtectionDomain().getCodeSource().getLocation()を実行しました。HttpServletResponse実装の場所がわかったので、それをIDEのクラスパスに追加しました: /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar!/weblogic/servlet/internal/ServletResponseImpl.class (公式の12.1.2.4 dockerイメージより)。
WEB-INF/weblogic.xmlウェブアプリケーションディスクリプタでこれを設定できることがわかりました。こんな感じです(1.9 XSDバージョンを
お使いのWebLogicと互換性のあるバージョンに置き換えてください):
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
http://xmlns.oracle.com/weblogic/weblogic-web-app/1.9/weblogic-web-app.xsd">
<context-root>/app</context-root>
<container-descriptor>
<redirect-with-absolute-url>false</redirect-with-absolute-url>
</container-descriptor>
</weblogic-web-app>
XSDファイルのコメントより:redirect-with-absolute-url要素がfalseに設定されている場合、サーブレットコンテナはリダイレクトのlocationヘッダー内の相対URLを絶対URLに変換しません。
