WeblogicにおけるDWRの「Session Error」問題
2010/12/14 16:22Update
WeblogicにおけるDWRの「Session Error」問題の原因究明及び解決方法について
現象:
TomcatやJBossなどで正常に動作しているDWR/Ajaxの呼び出しは、Weblogicに配置し画面を実行したところ、「Session Error」がとのメッセージが表示され、正常に動作してくれませんでした。
原因:
DWRのCSRF攻撃チェックエラー時出たエラーのようです。
org.directwebremoting.dwrp.Batch
private void checkNotCsrfAttack(HttpServletRequest request)
{
if(request.isRequestedSessionIdValid() && request.isRequestedSessionIdFromCookie())
{
String headerSessionId = request.getRequestedSessionId();
if(headerSessionId.length() > 0)
{
String bodySessionId = getHttpSessionId();
if(!bodySessionId.startsWith(headerSessionId)) //ここ!DWR AJAXのSession IDとクッキーのjsessionidは等しくない場合
throw new SecurityException("Session Error");
}
}
}
Weblogicの場合、クッキーに 値の違い2つSessionIDがあるようです。
どうやら、DWRは、クッキーに 値の違い2つSessionIDを考慮していなかったようです。
ちなみに、新しいバージョンのDWRでは、
org.directwebremoting.dwrp.Batch
/**
* Check that this request is not subject to a CSRF attack
* @param request The original browser's request
* @param sessionCookieName "JSESSIONID" unless it has been overridden
*/
private void checkNotCsrfAttack(HttpServletRequest request, String sessionCookieName)
{
// A check to see that this isn't a csrf attack
// http://en.wikipedia.org/wiki/Cross-site_request_forgery
// http://www.tux.org/~peterw/csrf.txt
if (request.isRequestedSessionIdValid() && request.isRequestedSessionIdFromCookie())
{
String headerSessionId = request.getRequestedSessionId();
if (headerSessionId.length() > 0)
{
String bodySessionId = getHttpSessionId();
// Normal case; if same session cookie is supplied by DWR and
// in HTTP header then all is ok
if (headerSessionId.equals(bodySessionId))
{
return;
}
//↓を追加
// Weblogic adds creation time to the end of the incoming
// session cookie string (even for request.getRequestedSessionId()).
// Use the raw cookie instead
Cookie[] cookies = request.getCookies();
for (int i = 0; i < cookies.length; i++)
{
Cookie cookie = cookies[i];
if (cookie.getName().equals(sessionCookieName) &&
cookie.getValue().equals(bodySessionId))
{
return;
}
}
// Otherwise error
log.error("A request has been denied as a potential CSRF attack.");
throw new SecurityException("Session Error");
}
}
}
のようになっていますので、Session Errorが出ないはずです。
※ちなみに、80ポートの場合出ないようです。
解決方法
1)DWRライブラリをより新しいバージョンにアップグレード
2)古いバージョンをそのまま使いたい場合、web.xmlに次のように定義する必要がある
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
<!-- ↓を追加 -->
<init-param>
<param-name>crossDomainSessionSecurity</param-name>
<param-value>false</param-value>
</init-param>
</servlet>
これで解決。
Sponsored Link
Comments
- Relative Articles
- Javaアプリのデバッグ及びTomcatやJBoss、Weblogic、JRunなどでのリモートデバッグ方法 - (2010/12/17 16:36)
- WebLogic Server 用の Java 仮想マシン (JVM) のチューニング - (2009/06/29 15:42)