PortalFilter問題 その3

ようやく、この問題が解決。解決方法は、PortalRequestWrapperでHttpServletRequestWrapperを継承するのではなく、HttpServletRequestをインターフェースする。原因は、コンテキストパスがApplicationDispatcherで異なるみたいで、ApplicationHttpRequestでcrossContextがtrueになり、セッションを新規生成するみたい。もう少し、Tomcatのコードをみた方がいいかな。

PortalFilter問題 その2

どうやら、Tomcatが親RequestをApplicationHttpRequestに差し替えられるのが原因に見える。Tomcatの以下のApplicationDispatcherのコードで変えられていると思われる。

/**
* Create and return a request wrapper that has been inserted in the
* appropriate spot in the request chain.
*/
private ServletRequest wrapRequest() {
// Locate the request we should insert in front of
ServletRequest previous = null;
ServletRequest current = outerRequest;
while (current != null) {
if ("org.apache.catalina.servlets.InvokerHttpRequest".
equals(current.getClass().getName()))
break; // KLUDGE - Make nested RD.forward() using invoker work
if (!(current instanceof ServletRequestWrapper))
break;
if (current instanceof ApplicationHttpRequest)
break;
if (current instanceof ApplicationRequest)
break;
if (current instanceof Request)
break;
previous = current;
current = ((ServletRequestWrapper) current).getRequest();
}
// Instantiate a new wrapper at this point and insert it in the chain
ServletRequest wrapper = null;
if ((current instanceof ApplicationHttpRequest) ||
(current instanceof Request) ||
(current instanceof HttpServletRequest)) {
// Compute a crossContext flag
HttpServletRequest hcurrent = (HttpServletRequest) current;
boolean crossContext = false;
if ((outerRequest instanceof ApplicationHttpRequest) ||
(outerRequest instanceof Request) ||
(outerRequest instanceof HttpServletRequest)) {
HttpServletRequest houterRequest =
(HttpServletRequest) outerRequest;
Object contextPath = houterRequest.getAttribute
(Globals.INCLUDE_CONTEXT_PATH_ATTR);
if (contextPath == null) {
// Forward
contextPath = houterRequest.getContextPath();
}
crossContext = !(context.getPath().equals(contextPath));
}
wrapper = new ApplicationHttpRequest
(hcurrent, context, crossContext);
} else {
wrapper = new ApplicationRequest(current);
}
if (previous == null)
outerRequest = wrapper;
else
((ServletRequestWrapper) previous).setRequest(wrapper);
wrapRequest = wrapper;
return (wrapper);
}

うーん、ApplicationHttpRequestについて、理解する必要があるな・・・。

PortalFilter

いや~、はまっている。adminで初めてログインしたときにパスワードを変更するところではまっている。中身について説明すると、PasswordCredentialValveImpl#invokeでパスワードの有効期限が切れていたりすると、プロファイルでsecurityに定義された流れでPSMLを探す。つまり、PasswordCredentialValveImplで表示するページをコントロールしている。adminで初めてログインするときには、PasswordCredential#isUpdateRequiredがtrueになっているため、ページが飛ばされる。っで、my-account.psmlが表示され、パスワード変更ポートレットが表示される。次に、新しいパスワードを入力し、送信すると、ChangePasswordPortletのprocessActionで新しいSubjectを生成して、JetspeedRequestContextのセッション(つまり、ポートレットのセッションではなく、J2のセッション)に入れる。で、このセッションで問題が発生している!PortalFilterをかませたときだけ、どうやら、新規にセッションが作られているみたいだ。そういわけで、謎のセッションに新しいSubjectを入れて、結局、PortalFilterでセッションから古いSubjectを再度取得して、isUpdateRequiredがtrueのままなので、再び、my-account.psmlを表示する。まずは、なぜ、PortalFilterをかませたときだけ、謎のセッションが来るのかを突き止める必要がある。現在の予想では、ラップしているところに問題があるような気もしている。コード内では、getRequest()でラップしたやつをとったりする場合がいくつかあるし。というわけで、調査中。結構、ややこしいので、調べるのに時間がかかっているな・・・。