細說shiro之六:session管理



官網:https://shiro.apache.org/

我們先來看一下shiro中關於Session和Session Manager的類圖。

如上圖所示,shiro自己定義了一個新的Session接口,用於統一操作接口,並通過SessionManager實現Session管理。
其中的3個實現類HttpServletSession,SimpleSession和StoppingAwareProxiedSession是我們經常需要打交道的。

HttpServletSession

首先,我們來看看org.apache.shiro.web.session.HttpServletSession的實現。

public HttpServletSession(HttpSession httpSession, String host) {
    if (httpSession == null) {
        String msg = "HttpSession constructor argument cannot be null.";
        throw new IllegalArgumentException(msg);
    }
    if (httpSession instanceof ShiroHttpSession) {
        String msg = "HttpSession constructor argument cannot be an instance of ShiroHttpSession.  This " +
                "is enforced to prevent circular dependencies and infinite loops.";
        throw new IllegalArgumentException(msg);
    }
    this.httpSession = httpSession;
    if (StringUtils.hasText(host)) {
        setHost(host);
    }
}

顯然,HttpServletSession只是簡單對javax.servlet.http.HttpSession進行了封裝,即:
在Web應用程序中,所有對Session相關的操作最終都是對javax.servlet.http.HttpSession進行的。

通過對上述Subject.login()的時序圖分析可以知道:
在Web應用程序中,Shiro確實是通過ServletContainerSessionManager獲取到容器創建的HttpSession再封裝為HttpServletSession的。
也就是說,Subject.login()登錄成功后用戶的認證信息實際上是保存在HttpSession中的。如果此時Web應用程序部署了多實例,必須要進行Session同步。
我們知道,SecurityManager是整個Shiro框架的核心控制器,在SpringMVC中集成Shiro時,就需要明確配置對應的SecurityManager。

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. -->
    <property name="realm" ref="myRealm" />
</bean>

而在org.apache.shiro.web.mgt.DefaultWebSecurityManager的實現中,使用的SessionManager就是ServletContainerSessionManager。

public DefaultWebSecurityManager() {
    super();
    ((DefaultSubjectDAO) this.subjectDAO).setSessionStorageEvaluator(new DefaultWebSessionStorageEvaluator());
    this.sessionMode = HTTP_SESSION_MODE;
    setSubjectFactory(new DefaultWebSubjectFactory());
    setRememberMeManager(new CookieRememberMeManager());
    setSessionManager(new ServletContainerSessionManager()); // 配置Session Manager
}

SimpleSession

shiro具備完善的Session管理機制,當在命令行程序中使用Shiro框架時,同樣可以執行與Web應用程序一樣的Session操作。
此時,Shiro實際上使用SimpleSession實現。

StoppingAwareProxiedSession

實際上,StoppingAwareProxiedSession僅僅是一個Session包裝類,即:
無論是HttpServletSession還是SimpleSession,在執行Subject.login()時保存到Subject中的Session都是StoppingAwareProxiedSession對象。

private class StoppingAwareProxiedSession extends ProxiedSession {

    private final DelegatingSubject owner;

    private StoppingAwareProxiedSession(Session target, DelegatingSubject owningSubject) {
        super(target);
        owner = owningSubject;
    }

    public void stop() throws InvalidSessionException {
        super.stop();
        owner.sessionStopped();
    }
}

【參考】
https://shiro.apache.org/session-management.html


免責聲明!

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



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