Shiro DefaultWebSessionManager的設計概念


默認的web應用Session管理器,主要是涉及到Session和Cookie

具備了SessionIdCookie、SessionIdCookie啟用開關

涉及到的行為:添加、刪除SessionId到Cookie、讀取Cookie獲得SessionId

構造器

public DefaultWebSessionManager() {
    // Cookie模板,支持Set注入,用戶可以自定義模板
    Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
// 提升Cookie安全性,防止XSS攻擊 cookie.setHttpOnly(
true); this.sessionIdCookie = cookie;
   // SessionIdCookie啟用開關
this.sessionIdCookieEnabled = true; this.sessionIdUrlRewritingEnabled = true; }

用戶自定義Cookie模板

<bean id="shiroCookieTemplate" class="org.apache.shiro.web.servlet.SimpleCookie">
    <constructor-arg name="name" value="JSESESSIONIDCOOKIE" />
    <property name="path" value="/" />
    <property name="httpOnly" value="true" />
</bean>

使用模板創建Cookie

Cookie template = getSessionIdCookie();
Cookie cookie = new SimpleCookie(template);

public SimpleCookie(Cookie cookie) {
    this.name = cookie.getName();
    this.value = cookie.getValue();
    this.comment = cookie.getComment();
    this.domain = cookie.getDomain();
    this.path = cookie.getPath();
    this.maxAge = Math.max(DEFAULT_MAX_AGE, cookie.getMaxAge());
    this.version = Math.max(DEFAULT_VERSION, cookie.getVersion());
    this.secure = cookie.isSecure();
    this.httpOnly = cookie.isHttpOnly();
}

Session創建的過程中

protected void onStart(Session session, SessionContext context) {
    super.onStart(session, context);

    if (!WebUtils.isHttp(context)) {
        log.debug("SessionContext argument is not HTTP compatible or does not have an HTTP request/response " +
                "pair. No session ID cookie will be set.");
        return;

    }
    HttpServletRequest request = WebUtils.getHttpRequest(context);
    HttpServletResponse response = WebUtils.getHttpResponse(context);

    // 判斷是否開啟了SessionIdCookie
    if (isSessionIdCookieEnabled()) {
        Serializable sessionId = session.getId();
        // 將SessionId存儲到Cookie中
        storeSessionId(sessionId, request, response);
    } else {
        log.debug("Session ID cookie is disabled.  No cookie has been set for new session with id {}", session.getId());
    }

    request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
    request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
}
private void storeSessionId(Serializable currentId, HttpServletRequest request, HttpServletResponse response) {
    if (currentId == null) {
        String msg = "sessionId cannot be null when persisting for subsequent requests.";
        throw new IllegalArgumentException(msg);
    }
    Cookie template = getSessionIdCookie();
    Cookie cookie = new SimpleCookie(template);
    String idString = currentId.toString();
    cookie.setValue(idString);
    // 給瀏覽器添加Cookie:response.addHeader("Set-Cookie", "JSESESSIONIDCOOKIE=UUID666777888; Path=/; HttpOnly");
    cookie.saveTo(request, response);
    log.trace("Set session ID cookie for session with id {}", idString);
}

參考:使用HttpOnly提升Cookie安全性

獲得Session的Id

public Serializable getSessionId(SessionKey key) {
// 首先試圖從SessionKey中獲得Session的Id Serializable id
= super.getSessionId(key); if (id == null && WebUtils.isWeb(key)) { ServletRequest request = WebUtils.getRequest(key); ServletResponse response = WebUtils.getResponse(key);
     // 如果沒有獲得到再試圖從Cookie中獲得 id
= getSessionId(request, response); } return id; }

Session過期

protected void onExpiration(Session s, ExpiredSessionException ese, SessionKey key) {
    // 首先更新介質中的Session
    super.onExpiration(s, ese, key);
    // 然后刪除SessionIdCookie
    onInvalidation(key);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM