maga****@hagan*****
maga****@hagan*****
2011年 4月 21日 (木) 23:04:43 JST
船田と申します。 ロードバランサーをフロントにWebサーバを経由してアプリケーションサーバにglassfishという環境でWicket1.4.17を使用しています。 HTTPSによる通信はロードバランサーまでで、以降はプロトコルごとに ポートを振り分けてHTTPで流しています。 http://xxx で始まるページから、@RequireHttpsを指定したPageに遷移して https://xxx で始まるページを表示させようとしています。 Applicatioクラスでは、以下のように指定しました。 @Override protected IRequestCycleProcessor newRequestCycleProcessor() { return new HttpsRequestCycleProcessor(new HttpsConfig(80, 443)); } HTTPでHTTPSのページにアクセスしようとするので Wicketは、このプロトコルで表示すべきページでないと判断し https://xxx で始まるURLを生成してリダイレクトをかけようとします。 そして、 https://xxx で始まるリクエストは、ロードバランサーが http://xxx に変換してバックエンドに流します。 結果、 WicketにはHTTP通信で届き、 Wicketがhttps:// でリダイレクト……という無限ループが発生します。 リダイレクトをかけているのは、 SwitchProtocolRequestTargetというクラスです。 public static IRequestTarget requireProtocol(Protocol protocol, IRequestTarget target) { RequestCycle requestCycle = RequestCycle.get(); WebRequest webRequest = (WebRequest)requestCycle.getRequest(); HttpServletRequest request = webRequest.getHttpServletRequest(); if (protocol == null || protocol == Protocol.PRESERVE_CURRENT || request.getScheme().equals(protocol.toString().toLowerCase())) { return null; } else { return new SwitchProtocolRequestTarget(protocol, target); } } request.getScheme()で現在使用中のプロトコルをみています。 glassfishが使用しているCoyoteRequestではsetScheme()が空実装なので事前に細工することもできません。 回避策として パッケージスコープであるSwitchProtocolRequestTargetを 強引に継承して、localportを見て判断するようなコードを書きました。 switch (protocol) { case HTTP: port = HTTPの時に使用する内部ポート; break; case HTTPS: port = HTTPSの時に使用する内部ポート; break; } if (protocol == null || protocol == Protocol.PRESERVE_CURRENT || request.getLocalPort() == port) { SwitchProtocolRequestTargetを呼び出している箇所も Wicketが持っている拡張ポイントではないので、 こういう書き方でよいのか悩んでいます。 Webサーバをフロント、アプリケーションサーバをバックエンドにして 内部の通信はすべてHTTPで行うという構成は よくある環境だと思うのですが、どのように実装するのが正しいのでしょうか? 以上、よろしくおねがいします。