Shiro學習筆記(6)-Session

前言

Shiro本身提供完整的Session管理(無論是在什麼環境),通過Session,可以自定義一些屬性讓shiro進行管理(例如可以存儲密碼進行定期的保存)。接下來,本篇文章會着重講解在Shiro中如何使用Session以及Session的一些特性。

使用Session

Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
session.setAttribute("key", "value");

和之前的代碼類似,獲取Session也是通過Subject對象。並且getSession()默認是調用的getSession(true)。當參數爲true是,存在Session則直接返回,如果不存在則創建一個新的;當傳遞false時,則不創建Session。

SessionManager

從名字就可以看出,SessionManager是用來管理所有Subject的Session的,隸屬於SecurityManager管理。因此可以通過配置化(shiro.ini)的形式自定義SessionManger實現。如下所示

[main]
...
sessionManager = com.mamba.bootstrap.SessionManagerImplementation
securityManager.sessionManager = $sessionManager

需要注意的是我們通常會使用Shiro自帶的SessionManager。

Session timeout

Session默認也有過期時間,默認30分鐘後時失效,可以通過配置的方式來設置全局失效時間

[main]
...
# 3,600,000 milliseconds = 1 hour
securityManager.sessionManager.globalSessionTimeout = 3600000

如果想要設置單個session的過期時間,則可以調用單獨的setTimeout方法進行設置

Session Listeners

Shiro也支持針對Session的監聽事件,可以在session啓動、停止、過期等狀態做出響應。針對SessionListeners的配置如下所示:

[main]
...
aSessionListener = com.mamba.sessionListener1
anotherSessionListener = com.mamba.sessionListener2

securityManager.sessionManager.sessionListeners = $aSessionListener, $anotherSessionListener.

需要注意配置的監聽器是針對所有session進行配置的

Session存儲

  • SeesionDao:用來保存Session中的數據,可以通過實現SeesionDao決定Session數據存放的方式.關於SessionDao的配置如下:
[main]
...
sessionDAO = com.mamba.SessionDAO
securityManager.sessionManager.sessionDAO = $sessionDAO

需要注意的是,如果是在Web環境,不會默認使用SessionDao。需要進行如下聲明來使用shiro自帶的WebSessionManager

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager

EHCache SessionDAO

  • Shiro支持EhCache作爲Session的存儲方式,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來指定使用哪種緩存存儲方式。

  • 配置EhCache
    shiro提供了 EhCache的默認配置ehcache.xml,內容如下:
<cache name="shiro-activeSessionCache"
       maxElementsInMemory="10000"
       overflowToDisk="true"
       eternal="true"
       timeToLiveSeconds="0"
       timeToIdleSeconds="0"
       diskPersistent="true"
       diskExpiryThreadIntervalSeconds="600"/>

shiro也支持用戶自定義緩存參數,但是需要注意的是overflowToDisk和eternal這兩個參數必須要存在。並且需要指定自定義配置文件的路徑

shiroCacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
shiroCacheManager.cacheManagerConfigFile = classpath:conf/ehcache-shiro.xml

並且在具體使用緩存參數的時候需要指定name

sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionDAO.activeSessionsCacheName = shiro-activeSessionCache

自定義Session Id

首先,Shiro默認提供了一個Session Id 生成器,使用的是JavaUuidSessionIdGenerator。如果想使用自己定義的生成器,則需要通過實現SessionIdGenerator接口,並且具體的配置如下:

[main]
...
sessionIdGenerator = com.my.session.SessionIdGenerator
securityManager.sessionManager.sessionDAO.sessionIdGenerator = $sessionIdGenerator

Session定期檢查

如果沒有Session的定期檢查,會出現一種情況:例如用戶是非正常退出登錄,shiro並不知道需要關閉當前的session,久而久之session數據會被填充滿。爲了防止這種情況的發生,Shiro默認提供了ExecutorServiceSessionValidationScheduler來對Session定期進行檢查,默認是一個小時。如果想要自定義時間,需要進行如下配置:

[main]
...
sessionValidationScheduler = org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler
# Default is 3,600,000 millis = 1 hour:
sessionValidationScheduler.interval = 3600000

securityManager.sessionManager.sessionValidationScheduler = $sessionValidationScheduler

自定義SessionValidationScheduler

如果不想使用shiro提供的默認SessionValidationScheduler,我們還可以進行指定創建,需要實現SessionValidationScheduler接口,具體的配置如下:

[main]
...
sessionValidationScheduler = com.foo.my.SessionValidationScheduler
securityManager.sessionManager.sessionValidationScheduler = $sessionValidationScheduler

禁用Session定期檢查

如果默認不想使用這個功能(可能你自己通過外部的工具或者其他方式解決了這個問題),可以通過如下配置來禁用:

[main]
...
securityManager.sessionManager.sessionValidationSchedulerEnabled = false

注意這種方式只是停止了定期檢查Session的數據,但是在每次查詢的時候還是進行驗證,如果想要徹底禁止Session檢查(可能有需要查過期Session或者其他數據的需求),那麼需要進行如下配置

[main]
...
securityManager.sessionManager.deleteInvalidSessions = false

需要注意的是,如果禁止刪除Session。你需要自己手動進行驗證,防止存儲空間用光。一般情況下,都應該允許自動地Session檢查

Session集羣

Shiro支持Session集羣的方式來存儲session的數據,具體的集羣方式可以指定決定(EhCache、redis等都可以實現集羣)。關於如何在Shiro中觸發集羣的配置主要有兩種方式、具體如下所示:

#This implementation would use your preferred distributed caching product's APIs:
activeSessionsCache = my.org.apache.shiro.cache.CacheImplementation

sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionDAO.activeSessionsCache = $activeSessionsCache

securityManager.sessionManager.sessionDAO = $sessionDAO

這種方式通過配置SessionDao的activeSessionsCache來實現,還有一種方式如下:

cacheManager = my.org.apache.shiro.cache.CacheManagerImplementation
 
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
 
sessionDAO.activeSessionsCacheName = shiro-activeSessionsCache
 
securityManager.sessionManager.sessionDAO = $sessionDAO
 
securityManager.cacheManager = $cacheManager

這種方式通過配置securityManager.cacheManager的來實現。

注意,關於集體如何使用存儲需要自己實現Cache接口接口

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章