SessionManager是在應用程序中爲全部Subject提供Session的管理,包括建立,刪除,失效及驗證等。同其的核心組件同樣,SessionManager 也是一個由SecurityManager 維護的頂級組件。 在Shiro中默認提供了一個SessionManager的實現DefaultSessionManager。DefaultSessionManager 提供一個應用程序所需的全部企業級會話管理。能夠在任何應用程序中使用。 若是想自定義一個SessionManager,可在Shiro.ini中配置。例如: [main] … sessionManager = com.foo.my.SessionManagerImplementation securityManager.sessionManager = $sessionManager 在系統中SessionManager 能夠經過JavaBean 風格的getter/setter 方法獲取或設置(getSessionManager()/setSessionManager())。 下面介紹默認的SessionManager包含的一些額配置項: Session Timeout 默認是30 分鐘。也就是說,若是任何Session 建立後閒置(未被使用,未被更新)的時間超過了30 分鐘,那麼該Session 就被認爲是過時的,且不容許再被使用。 你能夠經過globalSessionTimeout 屬性來爲全部的會話定義默認的超時時間。例如,若是你想超時時間是一個小時而不是30 分鐘: [main] … # 3,600,000 milliseconds = 1 hour securityManager.sessionManager.globalSessionTimeout = 3600000 Per-Session Timeout 上面的globalSessionTimeout 值默認是爲全部新建的Session 使用的。你能夠在每個會話的基礎上控制超時時間經過設置單獨的會話超時時間值。與上面的globalSessionTimeout 同樣,該值以毫秒(不是秒)爲時間單位。 Session Listeners Shiro 支持SessionListener 概念來容許你對發生的重要會話做出反應。你能夠實現SessionListener 接口(或擴展易用的SessionListenerAdapter)來與相應的會話操做做出反應。 因爲默認的SessionManager sessionListeners 屬性是一個集合,你能夠對SessionManager 配置一個或多個listener 實現,就像其餘在shiro.ini 中的集合同樣: [main] … aSessionListener = com.foo.my.SessionListener anotherSessionListener = com.foo.my.OtherSessionListener securityManager.sessionManager.sessionListeners = $aSessionListener, $anotherSessionListener, etc. 當任何會話事件發生時,SessionListeners 都會被通知——不只僅是對一個特定的會話。 Session Storage 每當一個會話被建立或更新時,它的數據須要持久化到一個存儲位置以便它可以被稍後的應用程序訪問。一樣地,當一個會話失效且再也不被使用時,它須要從存儲中刪除以便會話數據存儲空間不會被耗盡。SessionManager 實現了這些Create/Read/Update/Delete(CRUD)操做作爲內部組件,同時,經過SessionDAO反映了數據訪問對象(DAO)設計模式。 SessionDAO 的做用是你可以經過該接口來與你想要的任何數據存儲進行通訊。這意味着你的會話數據能夠駐留在內存中,文件系統,關係數據庫或NoSQL 的數據存儲,或其餘任何你須要的位置。 你能夠將任何SessionDAO 實現做爲一個屬性配置在默認的SessionManager 實例上。例如,在shiro.ini 中: [main] … sessionDAO = com.foo.my.SessionDAO securityManager.sessionManager.sessionDAO = $sessionDAO Shiro 已經有一些很好的SessionDAO 實現,你能夠當即使用或實現你須要的子類。 EHCache SessionDAO EHCache 默認是沒有啓用的,但若是你不打算實現你本身的SessionDAO,那麼強烈地建議你爲Shiro 的SessionManagerment 啓用EHCache 支持。EHCache SessionDAO 將會在內存中保存會話,並支持若內存不足時可溢出到磁盤。這對確保你在運行時不會隨機地「丟失」會話是很是好的。 爲全部Shiro 的緩存須要使用EHCache: [main] sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO securityManager.sessionManager.sessionDAO = $sessionDAO cacheManager = org.apache.shiro.cache.ehcache.EhcacheManager securityManager.cacheManager = $cacheManager 最後一行,securityManager.cacheManager = $cacheManager,爲全部Shiro 的須要配置了一個CacheManager。該CacheManager 實例會自動地直接傳送到SessionDAO(經過EnterpriseCacheSessionDAO 實現CacheManagerAware 接口的性質)。 而後,當SessionManager 要求EnterpriseCacheSessionDAO 去持久化一個Session 時,它使用一個EHCache 支持的Cache實現去存儲Session 數據。 Custom Session IDs Shiro 的SessionDAO 在建立一個新的會話時使用一個內置的SessionIdGenerator 組件來產生一個新的Session ID。該ID 生成後,被指派給新近建立的Session 實例,而後該Session 經過SessionDAO 被保存下來。 默認的SessionIdGenerator 是一個JavaUuidSessionIdGenerator,它能產生基於Java UUIDs 的String IDs。該實現可以支持全部的生產環境。 若是它不符合你的須要,你能夠實現SessionIdGenerator 接口並在Shiro 的SessionDAO 實例上配置該實現。例如,在shiro.ini 中: [main] ... sessionIdGenerator = com.my.session.SessionIdGenerator securityManager.sessionManager.sessionDAO.sessionIdGenerator = $sessionIdGenerator Session Validation & Scheduling Sessions 必須被驗證,這樣任何無效(過時或中止)的會話可以從會話數據存儲中刪除。這保證了數據存儲不會因爲不能再次使用的會話而致使寫入超時。 因爲性能上的緣由,僅僅在Sessions 被訪問(也就是subject.getSession())時驗證它們是否中止或過時。這意味着,若是沒有額外的按期驗證,Session orphans(孤兒)將會開始填充會話數據存儲。 會話孤兒,若是它們沒有按期清除,將會填充會話數據存儲(這是很糟糕的)。所以,爲了防止丟放孤兒,SessionManager 實現支持SessionValidationScheduler 的概念。SessionValidationScheduler 負責按期地驗證會話以確保它們是否須要清理。 Default SessionValidationScheduler 默承認用的SessionValidationScheduler 在全部環境中都是ExecutorServiceSessionValidationScheduler,它使用JDK ScheduledExecutorService 來控制驗證頻率。 默認地,該實現每小時執行一次驗證。你能夠經過指定一個新的ExecutorServiceSessionValidationScheduler 實例並指定不一樣的間隔(以毫秒爲單位)改變速率來更改驗證頻率: [main] … sessionValidationScheduler = org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler # Default is 3,600,000 millis = 1 hour: sessionValidationScheduler.interval = 3600000 securityManager.sessionManager.sessionValidationScheduler = $sessionValidationScheduler Custom SessionValidationScheduler 若是你但願提供一個自定義的SessionValidationScheduler 實現,你能夠指定它做爲默認的SessionManager 實例的一個屬性。例如,在shiro.ini 中: [main] … sessionValidationScheduler = com.foo.my.SessionValidationScheduler securityManager.sessionManager.sessionValidationScheduler = $sessionValidationScheduler Disabling Session Validation 在某些狀況下,你可能但願禁用會話驗證項,因爲你創建了一個超出了Shiro 控制的進程來爲你執行驗證。例如,也許你正在使用一個企業的Cache 並依賴於緩存的Time To Live 設置來自動地去除舊的會話。或者也許你已經制定了一個計劃任務來自動清理一個自定義的數據存儲。在這些狀況下你能夠關掉session validation scheduling: [main] … securityManager.sessionManager.sessionValidationSchedulerEnabled = false 當會話從會話數據存儲取回數據時它仍然會被驗證,但這會禁用掉Shiro 的按期驗證。 Enable Session Validation somewhere 若是你關閉了Shiro 的session validation scheduler,你必須經過其餘的機制(計劃任務等)來執行按期的會話驗證。這是保證會話孤兒不會填充數據存儲的惟一方法。 Invalid Session Deletion 正如咱們上面所說的,進行按期的會話驗證主要目的是爲了刪除任何無效的(過時或中止)會話來確保它們不會填充會話數據存儲。 默認地,某些應用程序可能不但願Shiro 自動地刪除會話。例如,若是一個應用程序已經提供了一個SessionDAO 備份數據存儲查詢,也許是應用程序團隊但願舊的或無效的會話在必定的時間內可用。這將容許團隊對數據存儲運行查詢來判斷,例如,在上週某個用戶建立了多少個會話,或一個用戶會話的持續時間,或與之相似報告類型的查詢。 在這些情形中,你能夠關閉invalid session deletion 項。例如,在shiro.ini 中: [main] … securityManager.sessionManager.deletInvalidSessions = false 請注意!若是你關閉了它,你得爲確保你的會話數據存儲不耗盡它的空間複雜。你必須本身從你的數據存儲中刪除無效的會話! 還要注意,即便你阻止了Shiro 刪除無效的會話,你仍然應該使用某種會話驗證方式——要沒經過Shiro 的現有驗證機制,要麼經過一個你本身提供的自定義的機制(見上述的"Disabling Session Validation"獲取更多)。驗證機制將會更新你的會話記錄以反映無效的狀態(例如,何時它是無效的,它最後一次被訪問是何時,等等),即便你在其餘的一些時間將手動刪除它們。 若是你配置Shiro 來讓它不會刪除無效的會話,你得爲確保你的會話數據存儲不會耗盡它的空間負責。你必須親自從你的數據存儲刪除無效的會話! 另外請注意,禁用會話刪除並不等同於禁用session validation schedule(會話驗證調度)。你應該老是使用一個會話驗證調度機制——不管是Shiro 直接支持或者是你本身的。