Shiro官方快速入門10min例子源碼解析框架2-Session

来源:https://www.cnblogs.com/codflow/archive/2019/01/17/shiro_source_code_2.html
-Advertisement-
Play Games

Shiro自身維護了一套session管理組件,它可以獨立使用,並不單純依賴WEB/Servlet/EJB容器等環境,使得它的session可以任何應用中使用。 2-Session)主要介紹在quickstart例子中從獲取Subject後,由初始化獲取Session並寫入讀出session參數的完 ...


Shiro自身維護了一套session管理組件,它可以獨立使用,並不單純依賴WEB/Servlet/EJB容器等環境,使得它的session可以任何應用中使用

 

2-Session)主要介紹在quickstart例子中從獲取Subject後,由初始化獲取Session寫入讀出session參數的完整過程。

同樣,本篇本文使用的是shiro 1.3.2版本,配合源碼最佳~

psr5wpkh

Shiro自身提供了SessionManager的三種實現來支持不同的模式

DefaultSessionManager:Shiro自身維護的session,可在普通應用環境使用

DefaultWebSessionManager:獨立提供在shiro-web包中,繼承SessionManager,並額外支持WEB相關方法

ServletContainerSessionManager:使用Servlet容器提供Session管理,提供少量額外方法

 

vdq5frmh

 

在samples-quickstart例子中使用到的是DefaultSessionManager。

 

篇1(Shiro官方快速入門10min例子源碼解析框架1-初始化)中,1.2節DefaultSecurityManager是DefaultSessionManager的子類,在初始化DefaultSecurityManager時一同初始化DefaultSessionManager

 

在獲取到Subject後,繼續看samples-quickstart的代碼如何獲取和設置Session

Subject currentUser = SecurityUtils.getSubject();

2.1下一步是獲取Session,調用Subject的getSession方法

Session session = currentUser.getSession();

DelegatingSubject中,getSession()若無參數,則調用getSession(true),如果不需要Shiro 的Session功能可以調用getSession(false),

public Session getSession() {
        return getSession(true);
    }

 

調用DelegatingSubject.getSession(true),前半部分是日誌,及isSessionCreationEnabled()判斷(預設為ture)

public Session getSession(boolean create) {
        if (log.isTraceEnabled()) {
            log.trace("attempting to get session; create = " + create +
                    "; session is null = " + (this.session == null) +
                    "; session has id = " + (this.session != null && session.getId() != null));
        }

        if (this.session == null && create) {

            //added in 1.2:
            if (!isSessionCreationEnabled()) {
                String msg = "Session creation has been disabled for the current subject.  This exception indicates " +
                        "that there is either a programming error (using a session when it should never be " +
                        "used) or that Shiro's configuration needs to be adjusted to allow Sessions to be created " +
                        "for the current Subject.  See the " + DisabledSessionException.class.getName() + " JavaDoc " +
                        "for more.";
                throw new DisabledSessionException(msg);
            }

            log.trace("Starting session for host {}", getHost());
            SessionContext sessionContext = createSessionContext();
            Session session = this.securityManager.start(sessionContext);
            this.session = decorate(session);
        }
        return this.session;
    }

主要在後半部分sessionContext、session獲取,及decorate過程

l0gzso40

2.1.1獲取預設空白sessonContext,其為map的子類,

 

 

2.1.2構建session將sessionContext綁定到其中

 

2.1.3包裝session

 

2.1.2調用SessionsSecurityManager.start 其中sessionManager是DefaultSessionManager的實例

public Session start(SessionContext context) throws AuthorizationException {
        return this.sessionManager.start(context);
    }

其調用父類AbstractNativeSessionManager中的start方法

public Session start(SessionContext context) {
        Session session = createSession(context);
        applyGlobalSessionTimeout(session);
        onStart(session, context);
        notifyStart(session);
        //Don't expose the EIS-tier Session object to the client-tier:
        return createExposedSession(session, context);
    }

image

 

 

 

2.1.2.1構建Session

 

2.1.2.2設置session過期時間

 

 

2.1.2.3onStart操作,作為session監聽器點(本例無監聽器

 

2.1.2.4調用監聽器onStart(本例無監聽器

 

2.1.2.5創建

 

 

 

 

2.1.2.1繼而AbstractNativeSessionManager.createSession()調用AbstractValidatingSessionManager.createSession() 啟用session的驗證功能,

protected Session createSession(SessionContext context) throws AuthorizationException {
        enableSessionValidationIfNecessary();
        return doCreateSession(context);
    }

繼續調用DefaultSessionManager.doCreateSession(),DefaultSessionManager調用newSessionInstance,

protected Session doCreateSession(SessionContext context) {
        Session s = newSessionInstance(context);
        if (log.isTraceEnabled()) {
            log.trace("Creating session for host {}", s.getHost());
        }
        create(s);
        return s;
    }

獲得SimpleSessionFactory工廠後構建調用SimpleSessionFactory.createSession()

此時session中只有時間戳、session失效時間等信息

dy1l5tow

繼而調用DefaultSessionManager.create() 持久化session(由於例子中未設置外部DAO則使用的是MemorySessionDAO實例

protected void create(Session session) {
        if (log.isDebugEnabled()) {
            log.debug("Creating new EIS record for new session instance [" + session + "]");
        }
        sessionDAO.create(session);
    }

這一步中會 為session生成一個UUID作為sessionID,並保存到session中,調用storeSession()將session 及其ID保存在MemorySessionDAO實例中的一個ConcurrentMap sessions中

protected Serializable doCreate(Session session) {
        Serializable sessionId = generateSessionId(session);
        assignSessionId(session, sessionId);
        storeSession(sessionId, session);
        return sessionId;
    }

最後成功返回session

 

2.1.2.2依據全局session過期時間設置session並更新到sessionDAO

protected void applyGlobalSessionTimeout(Session session) {
        session.setTimeout(getGlobalSessionTimeout());
        onChange(session);
    }

hsmx3vg4

2.1.2.5

將SimpleSession轉化為外部可用的DelegatingSession

protected Session createExposedSession(Session session, SessionContext context) {
        return new DelegatingSession(this, new DefaultSessionKey(session.getId()));
    }

 

2.1.3將session包裝成統一的StoppingAwareProxiedSession,後續通過委托操作session內的方法

protected Session decorate(Session session) {
        if (session == null) {
            throw new IllegalArgumentException("session cannot be null");
        }
        return new StoppingAwareProxiedSession(session, this);
    }

 

vqn0nz1fruydqdo1

 

最後各處返回得到session

2.2在session中插入值

session.setAttribute("someKey", "aValue");

調用StoppingAwareProxiedSession父類方法ProxiedSession.setAttribute(),其中

public void setAttribute(Object key, Object value) throws InvalidSessionException {
        delegate.setAttribute(key, value);
    }

繼而調用DelegatingSession.setAttribute(),其中調用並調用AbstractNativeSessionManager.setAttribute(),參數sessionKey為當前DelegatingSession的sessionKey

public void setAttribute(SessionKey sessionKey, Object attributeKey, Object value) throws InvalidSessionException {
        if (value == null) {
            removeAttribute(sessionKey, attributeKey);
        } else {
            Session s = lookupRequiredSession(sessionKey);
            s.setAttribute(attributeKey, value);
            onChange(s);
        }
    }

image

 

 

 

2.2.1判斷來值是否為空

 

2.2.2.1

lookupRequiredSession(sessionKey)經過一系列過程,獲得sessionId,依據sessionId由sessionDAO從DAO中獲取simplesession實例

 

2.2.2.2空則刪除對應的session參數

2.2.3獲得的session設置參數

 

 

2.2.4sessionDAO中更新session

 

 

 

 

2.2在session中查找值

String value = (String) session.getAttribute("someKey");

調用StoppingAwareProxiedSession父類方法ProxiedSession.getAttribute(),

public Object getAttribute(Object key) throws InvalidSessionException {
        return delegate.getAttribute(key);
    }

與setAttribute()類似,從DAO中依據由sessionKey得到的sessionID獲得SimpleSession的實例,再調用其getAttribute方法獲得參數

public Object getAttribute(SessionKey sessionKey, Object attributeKey) throws InvalidSessionException {
        return lookupRequiredSession(sessionKey).getAttribute(attributeKey);
    }

 

至此一個簡單的Session獲取及參數寫入讀取便完成了

 

 

參考:

http://shiro.apache.org/10-minute-tutorial.html

http://shiro.apache.org/session-management.html

http://www.apache.org/dyn/closer.cgi/shiro/1.3.2/shiro-root-1.3.2-source-release.zip

 

轉載請註明作者及來源:https://www.cnblogs.com/codflow/


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本系列來自《編寫高質量代碼 改善python程式的91個建議》的讀書筆記整理。 ...
  • Shell是一個命令解釋器。它不僅是操作系統內核與用戶之間的絕緣層,同時也是一種功能相當強大的編程語言。一個Shell程式,通常稱為腳本,它是一個由系統調用,命令工具,軟體包和已編譯的二進位包"粘合" 起來的極易使用的工具。事實上,整個UNIX系統命令,軟體包和工具都能由一個shell腳本調用。如果 ...
  • 一、文件處理基本形式 二、打開文件的模式 三、操作文件的方法 ...
  • 哈哈,其實很簡單,寥寥幾行代碼網頁爬一部小說,不賣關子,立刻開始。 首先安裝所需的包,requests,BeautifulSoup4 控制台執行 pip install requests pip install BeautifulSoup4 如果不能正確安裝,請檢查你的環境變數,至於環境變數配置,在 ...
  • 因為http,https是無狀態的,也就是當我們連續兩次訪問同一個web網站,網站是無法分辨這兩次訪問是來自同一個人。對於它來說,這兩次訪問是沒有關係的。 就像是,我們進入了澡堂洗澡,中途要從入口出來接電話,可是當我們再次進去的時候,人家就不認識你了,還管著問你要貴賓卡呢!那麼怎麼讓這個門口迎賓能認 ...
  • 前兩次講了 Spark RPC 的基礎內容以及源碼時序分析。這次我們來看看Spark 如何用 RPC 實現心跳。 ...
  • 本文將帶你走進python3.7的新特性dataclass,通過本文你將學會dataclass的使用並避免踏入某些陷阱。 dataclass簡介 dataclass的使用 定義一個dataclass 深入dataclass裝飾器 數據類的基石——dataclasses.field 一些常用函數 da ...
  • Django 系列博客(十三) 前言 本篇博客介紹 Django 中的常用欄位和參數。 ORM 欄位 AutoField int 自增列,必須填入參數 primary_key=True。當 model 中如果沒有自增列,則會自動創建一個列名為 id 的列。 IntegerField 一個整數類型,範 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...