サーブレット3.0ノートのセッションCookie設定関連

5747 ワード

サーブレット3.0ノートのセッションCookie設定関連
サーブレット3.0にCookie(ここでいうCookieは、SessionとインタラクティブなCookie、すなわちよく言われるセッションCookieのみを指す)の比較的包括的な操作APIを追加する.最も際立った特性:SessionIDの名前(デフォルトは「JESSIONID」)を直接変更することをサポートし、クッキーにHttpOnly属性を設定してセキュリティを強化し、ある程度のクロスステーション攻撃を避けることをサポートします.
詳細については、「≪ステップ・リード|Step Read|emdw≫」セクションにアクセスしてください.
以前の実装
新しいAPIは簡単で便利なAPI操作セッションCookieを提供しているが、新しいAPIの前に、私たちは比較的硬い操作応答ヘッダを提供し、設定作業を完了することができる.以前のコードを見てみましょう.
/**
* Cookie
* @author yongboy
* @date 2011-1-19
* @version 1.0
*/
@WebFilter(dispatcherTypes = { DispatcherType.REQUEST }, urlPatterns = { "/*" })
public class CustomCookieFilter implements Filter {
private static final Log log = LogFactory.getLog(CustomCookieFilter.class);
private static final String CUSTOM_SESSION_ID = "YONGBOYID";
private static final String HTTP_ONLY = "HttpOnly";
private static final String SET_COOKIE = "SET-COOKIE";

public void destroy() {
}

public void doFilter(ServletRequest req, ServletResponse rep,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) rep;

if (response.containsHeader(SET_COOKIE)) {
log.info("haha,we have one new user visit the site ...");

String sessionId = request.getSession().getId();
String cookieValue = CUSTOM_SESSION_ID + "=" + sessionId + ";Path="
+ request.getContextPath() + ";" + HTTP_ONLY;

log.info(SET_COOKIE + ":" + cookieValue);

response.setHeader(SET_COOKIE, cookieValue);
}

chain.doFilter(req, response);
}

public void init(FilterConfig fConfig) throws ServletException {
}
}

ブロック実装により,要求毎の応答にSET−COOKIEヘッダが含まれているか否かを判断し,セッションCookieを書き換え,必要な属性を追加する.硬いが柔軟性が強い.
新しい仕様API
セッションCookieを操作するためのSessionCookieConfigインタフェースを追加する新しい仕様は、次の主な方法を把握する必要があります.
  • setName(String name)セッションIDの名前を変更します.デフォルトは「JESSIONID」
  • です.
  • setDomain(String domain)現在のCookieが存在するドメイン
  • を設定する.
  • setPath(String path)現在のCookieが存在する相対パス
  • を設定する.
  • setHttpOnly(boolean httpOnly)設定HttpOnly属性
  • をサポートするかどうか
  • setSecure(boolean secure)HTTPSセキュリティ接続を使用する場合は、その属性をtrue
  • とする必要がある.
  • setMaxAge(int maxAge)は、秒
  • の単位で生存時間を設定する.
    どのように使うかは便利で、サーブレットContextListenerリスナーの初期化方法で設定すればいいです.次の例では、JESSIONIDを変更し、HttpOnlyサポートを追加する方法を示します.
    /**     Session-Cookie       
    *
    * @author yongboy
    * @date 2011-1-19
    * @version 1.0
    */
    @WebListener
    public class SessionCookieInitialization implements ServletContextListener {
    private static final Log log = LogFactory
    .getLog(SessionCookieInitialization.class);

    public void contextInitialized(ServletContextEvent sce) {
    log.info("now init the Session Cookie");

    ServletContext servletContext = sce.getServletContext();

    SessionCookieConfig sessionCookie = servletContext
    .getSessionCookieConfig();
    sessionCookie.setName("YONGBOYID");
    sessionCookie.setPath(servletContext.getContextPath());
    sessionCookie.setHttpOnly(true);
    sessionCookie.setSecure(false);

    log.info("name : " + sessionCookie.getName() + "
    " + "domain:"
    + sessionCookie.getDomain() + "
    path:"
    + sessionCookie.getPath() + "
    age:"
    + sessionCookie.getMaxAge());

    log.info("isHttpOnly : " + sessionCookie.isHttpOnly());
    log.info("isSecure : " + sessionCookie.isSecure());
    }

    public void contextDestroyed(ServletContextEvent sce) {
    log.info("the context is destroyed !");
    }
    }

    SessionCookieConfigオブジェクトは、SessionContextオブジェクトから取得する必要があります.session Cookieの名前などのプロパティをさらにカスタマイズできます.
    従来のハードコーディングでも新しいAPIでも,ターゲットは一致し,生成されたヘッダ情報も完全に一致した.後者は、表示される操作応答メタデータを節約するために、より便利で迅速であることは間違いありません.
    現在のサイトの最初のリクエストでは、Set-Cookieのプロパティ値が応答ヘッダ情報から容易に表示されます.
    異なるブラウザプラットフォームでのテスト
  • Safari、IE 8、Opera 11ではすべて正常です
  • Firefox 3.6、Chrome 9.0、JESSIONIDは引き続き存在します.
    YONGBOYID=601A6C82D535343163B175A4FD5376EA; JSESSIONID=AA78738AB1EAD1F9C649F705EC64D92D; AJSTAT_ok_times=6; JSESSIONID=abcpxyJmIpBVz6WHVo_1s; BAYEUX_BROWSER=439-1vyje1gmqt8y8giva7pqsu1
  • すべてのブラウザで、SESSION IDは新しく設定されたYONGBOYID値に等しい(等しくなければ、問題は深刻!)
  • クライアントJSで正しいSESSIONI IDを取得できなくなりました.

  • Tomcatサーバ内蔵サポート
    Tomcat 6-7では、上記のようにCookie domain、name、HttpOnlyの設定を表示することなくconf/contextでサポートすることができる.xmlファイルで設定:
    <Context useHttpOnly="true", sessionCookieName="YONGBOYID", sessionCookieDomain="/servlet3" … >
    ...
    </Context>

    JAVAアプリケーションサーバ自体がセッションCookie設定をサポートしている以上,プログラムコードで再度符号化する必要はない.これは良い実践です:繰り返し車輪を作らないでください.
    ここでは、セッションの書き換えをテストするスクリプトを示します.
    <div style="margin: 40px; paddding: 10px">
    <div><a href="sessionCookieTest"> </a></div>
    <div><a href="<%=response.encodeURL("sessionCookieTest") %>"> </a></div>
    </div>

    書き換えられるURLアドレスは次のようなものです.
    http://localhost/servlet3/sessionCookieTest;YONGBOYID=19B94935D50245270060E49C9E69F5B6
    うーん、セッションCookieをキャンセルした後、修正したSESSION ID名が直接見えてきますが、もちろんHttpOnly属性もあまり意味がありません.
    忘れないでください.HttpOnlyを設定すると、クライアントのJSはセッションIDを取得できません.
    ステップ読み:
  • ウィキペディアのHttpOnlyに対する解釈
  • HTTP-only Cookieを利用してXSSの痛みを緩和する
  • Tomcat Context属性
  • HttpOnly Cookieとサイト間追跡