Shiro————会话管理
引言
本篇博客翻譯自Shiro 官方網(wǎng)站的 Session Manager 手冊。
網(wǎng)頁地址:http://shiro.apache.org/session-management.html
Shiro 會話管理支持的特性
- 基于POJO/J2SE(IoC容器友好的)- Shiro 中的所有東西都是基于接口的,而且是以 POJO作為實現(xiàn)。因此你可以很容易地配置所有兼容 JavaBean 的會話組件,如 JSON,YAML, Spring XML,或者類似的機制。你也可以很容易的擴展Shiro 的組件,或在必要情況下完全自定義 session 管理的功能。
- 簡單的自定義 Session 存儲 - 因為 Shiro 的 Session 對象是基于 POJO的,因此 Session 數(shù)據(jù)可以存儲在任意數(shù)量的數(shù)據(jù)源中。因此,你可以自定義你的應用 session 存儲的位置,例如,文件系統(tǒng)、內(nèi)存、分布式的網(wǎng)絡緩存、關(guān)系型數(shù)據(jù)庫,或者是專有數(shù)據(jù)存儲區(qū)。
- 不依賴容器的集群! - Shiro 的session 可以被任何緩存產(chǎn)品集群管理,如Ehcache + Terracotta, Coherence, GigaSpaces 等等。這意味著你只需要配置一次 Session 集群,不論你的應用會部署到哪種容器,你的 session 都將以同樣的方式聚集。不需要針對特定容器的配置。
- Heterogeneous Client Access?- Unlike EJB or Web sessions, Shiro sessions can be ‘shared’ across various client technologies. For example, a desktop application could ‘see’ and ‘share’ the same physical session used by the same user in a web application. We are unaware of any framework other than Shiro that can support this.
- 事件監(jiān)聽 - 事件監(jiān)聽允許你監(jiān)聽 session 的生命周期。你可以監(jiān)聽它們并對這些事件作出自定義的操作,例如,當某個用戶的 session 過期時更新數(shù)據(jù)庫的記錄。
- 主機地址保留 - Shiro Session 會保留發(fā)起主機的 IP 地址。因此,你可以據(jù)此來確定用戶的位置并作出相應的反應(通常在IP 關(guān)聯(lián)關(guān)系確定的 內(nèi)網(wǎng)環(huán)境比較有用)
- 支持用戶無操作/過期 - 由于用戶無操作而導致 Session 超時是人們期望看到的,但 session 可以通過 touch()方法保持“活躍”。這在富互聯(lián)網(wǎng)應用環(huán)境非常有用,用戶可能一直在使用桌面應用,而并沒有定期與服務端產(chǎn)生交互,但 server 端的 session 不應該因此而過期。
- Web 使用透明(無障礙感)?- Shiro 對 web 的支持 完全實現(xiàn)了和支持了 Servlet 2.5 對 Session 的規(guī)范(HttpSession 接口和與它相關(guān)的所有API)。也就是說你可以在已創(chuàng)建的 Web 應用中使用 Shiro 的Session ,而且不需要更改任何代碼。
- 可以使用在 SSO上 - 因為 Shiro 的Session 是基于 POJO 的,它們可以被存儲到任意的數(shù)據(jù)源上,而且,如果需要的話可以在多個應用間進行共享。它還可以提供簡單的登錄體驗,因為共享會話可以保留身份驗證狀態(tài)(單點登錄)。
使用 Session
和Shiro 中幾乎所有的東西一樣,要獲得 Session 對象,你需要和當前執(zhí)行的 用戶 產(chǎn)生某種作用。
Subject currentUser = SecurityUtils.getSubject();Session session = currentUser.getSession(); session.setAttribute( "someKey", someValue);currentUser.getSession() 方法默認調(diào)用了 currentUser.getSession(true)。
對于那些熟悉 HttpServletRequest API 的人,Subject.getSession(boolean create) 方法在功能上和HttpServletRequest.getSession(boolean create) 方法完全一致。
- 如果 Subject 已經(jīng)有了一個 Session ,布爾類型的參數(shù)將被忽略,而直接返回 session 對象。
- 如果 Subject 還沒有一個Session ,且參數(shù)為 true,就會創(chuàng)建一個 Session 對象并返回。
- 如果 Subject 還沒有一個 Session ,且參數(shù)為 false, 就不會創(chuàng)建 Session ,并且返回 null。
注意:getSession方法的調(diào)用在所有應用中都適用,即便不是web 應用。
subject.getSession(false) 在開發(fā)框架代碼確定不需要創(chuàng)建新的 Session 時,可以獲得良好的效果。
一旦你獲得了一個 Subject 的 Session ,你可以用它來做許多事情,例如設置和取出屬性,設置它的 timeout,等等。參考Session JavaDoc?查看更多信息。
會話管理器
SessionManager,顧名思義,管理應用中所有 subject 的 session? - 創(chuàng)建、刪除、無活動過期 等等。和其他 Shiro 中的架構(gòu)組件一樣,SessionManager 對象也是一個被SecurityManager 持有的頂級組件。
默認的 SecurityManager 實現(xiàn)默認使用開箱即用的 DefaultSessionManager。DefaultSessionManager可以提供所有企業(yè)級 session 管理特性,如 會話過期、清理等等,且同樣適用于所有類型的應用。
Web 應用
Web 應用可以使用不同的 SessionManager實現(xiàn)類。請參考 Web 文檔查看 web特定的 Session 管理信息。
和其他被 SecurityManager 管理的組件一樣, SessionManager 可以通過JavaBean的形式通過 get、set 方法組裝到所有 Shiro 默認的 SecurityManager 實現(xiàn)對象上(getSessionManager()/setSessionManager())?;蛘呃缦旅?#xff0c;使用 shiro.ini 配置文件:
[main] ... sessionManager = com.foo.my.SessionManagerImplementation securityManager.sessionManager = $sessionManager但是從頭創(chuàng)建一個 SessionManager 是一件非常復雜的任務,大多數(shù)人都不愿去做。Shiro的開箱即用的 SessionManager 實現(xiàn)是高度可定制和配置的,同時滿足大多數(shù)需要。本文檔其余部分的大部分假設您將在介紹配置選項時使用Shiro的默認SessionManager實現(xiàn),但是請注意,實際上您可以創(chuàng)建或插入幾乎任何您想要的東西。
Session 超時
默認情況下,SessionManager 的默認會話超時時間是 30分鐘。也就是說,如果任何 Session 創(chuàng)建后保持閑置(未使用,即 lastAccessedTime 沒有更新)超過 30 分鐘或更長,那么 Session 就可能過期,并且不允許再繼續(xù)使用。
你可以設置默認的 session 超時時間,使用 globalSessionTimeout 屬性來為所有的 session 定義默認的超時。例如,如果你希望超時時間是一小時而不是 30分鐘:
[main] ... # 3,600,000 milliseconds = 1 hour securityManager.sessionManager.globalSessionTimeout = 3600000單個 session 超時
globalSessionTimeout 限制所有新產(chǎn)生的 session 。你可以為每個 session 設置 timeout 屬性。和上面的 globalSessionTimeout一樣,這個值也是基于 毫秒的。
Session 監(jiān)聽器
Shiro 支持監(jiān)聽器的概念,允許你在一些非常重要的 session 事件發(fā)生時做出動作。你可以實現(xiàn) SessionListener 接口(或 繼承更方便的 SessionListenerAdapter)并且對 Session 操作做出相應的反應。
默認的 SessionManager的sessionListeners 屬性 是一個集合,你可以給 SessionManager 配置一個或者多個 監(jiān)聽器實現(xiàn):
[main] ... aSessionListener = com.foo.my.SessionListener anotherSessionListener = com.foo.my.OtherSessionListenersecurityManager.sessionManager.sessionListeners = $aSessionListener, $anotherSessionListener, etc.所有的 Session 事件
SessionListener 會監(jiān)聽所有的 session 事件,并不是只為了某一個 特定的session 。
Session 存儲
不論session 什么時候創(chuàng)建或更新,它的數(shù)據(jù)都需要持久化到一個存儲位置,這樣才能讓應用程序在接下來的操作中訪問到。同樣,當一個 Session 失效或者不再使用,也需要從存儲空間中刪除,以免存儲空間耗盡。SessionManager 的實現(xiàn)可以將 session? 的 CRUD操作委托給一個系統(tǒng)內(nèi)部的組件,即 SessionDAO ,它遵從 Data Access Object (DAO)設計模式。
通過實現(xiàn) SessionDAO 這個接口,你可以和任何你希望的數(shù)據(jù)存儲進行交互。也就是說,你可以把你的 session 數(shù)據(jù)放到內(nèi)存、或文件系統(tǒng)、或關(guān)系型數(shù)據(jù)庫、或NoSQL 數(shù)據(jù)庫中,或者其他任何地方。你可以完全掌控持久化行為。
你也可以配置任何形式的 SessionDAO 實現(xiàn)裝載到默認的SessionManager 實例中,例如,像下面 shiro.ini 這樣:
[main] ... sessionDAO = com.foo.my.SessionDAO securityManager.sessionManager.sessionDAO = $sessionDAO當然,人們也期望,Shiro 已經(jīng)準備了一些優(yōu)秀的 SessionDAO 的實現(xiàn),你可以開箱即用,或者繼承他們做個性化處理。
Web 應用注意
上面的?securityManager.sessionManager.sessionDAO = $sessionDAO 裝載方式只適用于當使用 Shiro 自己的 session 管理器的時候。Web 應用一般情況不使用這種本地session 管理器,而是保留 Servlet 容器的默認 session 管理器,然而這個管理器并不支持 Shiro 的SessionDAO。如果你希望在 Web 應用中使用 Shiro 提供的SessionDAO 接口來定制 session 存儲或 session 集群,你必須首先配置一個Shiro 自己的web session 管理器。例如:
[main] ... sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager securityManager.sessionManager = $sessionManager# Configure a SessionDAO and then set it: securityManager.sessionManager.sessionDAO = $sessionDAO(譯者注:Shiro native 我翻譯成了 Shiro 自己的,者應該是原文所表達的含義,即需要開發(fā)者在Web 應用中配置 Shiro 框架為 web應用專門定制的可以支持 SessionDAO 接口的 web session 管理器)
配置 SessionDAO 注意
Shiro 的默認配置 SessionManager 采用?in-memory-only?只讀內(nèi)存方式的Session 存儲,這并不適用于大多數(shù)生產(chǎn)應用。大多數(shù)生產(chǎn)應用會想要配置EHChached 支持并且提供自己的 SessionDAO實現(xiàn)。注意, Web應用使用基于Servlet 容器的SessionManager 作為默認實例因此不用擔心這個問題。這個問題只會在使用 Shiro 自己的SessionManager 的時候需要考慮。
EHCache SessionDAO
EHCache 不是默認可用的,但如果你不打算實現(xiàn)自己的 SessionDAO,那就強烈推薦為你的應用添加EHCache 來支持 Shiro 的Session 管理工作。EHCache SessionDAO 會將 session 存儲到內(nèi)存中,并支持當內(nèi)存逐漸吃緊的情況下溢出到磁盤。這可以非常良好的保證生產(chǎn)應用不會在運行時隨機 “丟失” Session。
使用 EHCache 作為你的默認選擇
如果你沒有自己定制化的 SessionDAO,一定(譯者注:這里原文是推薦的口吻)要在你的Shiro 配置中使用EHCache 。EHCache 不僅可以使你的 Session 受益,同樣也會對緩存鑒權(quán)、授權(quán)數(shù)據(jù)有所幫助。參考Chaching 文檔獲取更多幫助。
不依賴容器的 Session 集群
如果你迫切需要一個不依賴容器的 session 集群,那EHCache 同樣是不錯的選擇。你可以顯式插入一個 TerraCotta 到你的EHCache 中,并擁有一個不依賴容器的集群化的 session 緩存。再也不用擔心什么Tomcat、JBoss、Jetty、WebSphere 或者 WebLogic??定制的session 集群了。
為 Session 啟用EHCache 非常簡單。首先,確保你的項目中已經(jīng)有了 shiro-ehcache-<version>.jar 文件。
然后,下面的 shiro.ini 示例展示了如何使用 EHCache 支持所有 Shiro 緩存的需要(可不僅僅是 Session 支持哦):
[main]sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO securityManager.sessionManager.sessionDAO = $sessionDAOcacheManager = org.apache.shiro.cache.ehcache.EhCacheManager securityManager.cacheManager = $cacheManager最后一行,為所有 Shiro 的需要配置了一個 CacheManager。這個 CacheManager 實例會自動傳播到?SessionDAO(默認實現(xiàn)了 CacheManagerWare 接口的 EnterpriseCacheSessionDAO?)。
然后,當 SessionManager 要求??EnterpriseCacheSessionDAO??去持久化一個 session 的時候,它會使用一個EHCache 支持的 Cache 實現(xiàn)去存儲 session 數(shù)據(jù)。
web 應用
不要忘記 SessionDAO 是Shiro 框架自己的SessionManager 實現(xiàn)所具備的特性。Web 應用默認使用 基于 Servlet 容器的 SessionManager 是不支持 SessionDAO 的。如果你想在web 應用中使用基于EHCache 的 Session 存儲,就需要配置一個Shiro自己的 web SessionManager ,這已經(jīng)在前面有所說明。
EHCache Session 緩存配置
http://shiro.apache.org/session-management.html#ehcache-session-cache-configuration
未完待續(xù)......
?
?
?
總結(jié)
以上是生活随笔為你收集整理的Shiro————会话管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ssm项目集成ftp_ssm开发旅游信息
- 下一篇: Markdown简明使用