WeblogicにおけるDWRの「Session Error」問題

2010/12/14 16:22Update
TAGS: Weblogic | DWR | AJAX | Session

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>

これで解決。

有关作者
Syboos.jp編集長AJavaやオープンソース情報の執筆、Webサイトの開発や運営全般の業務に携わる。

Sponsored Link


Comments

用户名 (required)

Email (will not be published) (required)

URL

Evaluation