默認的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); }
獲得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); }