最近項目中用到的Session共享場景:兩個獨立應用,希望實作DB層共享使用者,而且使用者隻需要登入一次。
分析:這種場合,不适用單點,因為使用者資料并不需要單獨在第三方應用管理,而且添加單點也會增加整個系統的複雜度
兩種實作思路:Session資料存在DB中或者緩存Ehcache中
決策:考慮到查詢效率問題,使用緩存機制。
步驟如下:(已經過實際項目檢驗,如您遇到問題,請在評論中回複)
1. ehcache.xml配置<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ehcache>
<ehcache name="shiro" updateCheck="false" monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir/ehcache" />
<!-- 預設緩存配置. 自動失效:最後一次通路時間間隔300秒失效,若沒有通路過自建立時間600秒失效。->
<defaultCache maxEntriesLocalHeap="1000" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="600"
overflowToDisk="true" statistics="true" />
<!-- 會話緩存 -->
<cache name="shiro-activeSessionCache" maxEntriesLocalHeap="10000"
eternal="true"
timeToIdleSeconds="0" timeToLiveSeconds="0"
overflowToDisk="true" statistics="true" >
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
</cache>
<!-- 監聽服務,使用者監聽其它應用通過過來的session操作 -->
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost, port=40002,
socketTimeoutMillis=2000">
</cacheManagerPeerListenerFactory>
<!-- 提供服務,當本應用對session操作時,會複制到其它應用(如果是多個應用則需要在rmiUrls屬性寫多個url,并用中豎線分割 -->
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//localhost:40001/shiro-activeSessionCache">
</cacheManagerPeerProviderFactory>
</ehcache>
2. 配置(ini或者config)
1)配置CacheManager
/**
* 核心:SecurityManager,權限管理,這個類組合了登陸,登出,權限,session的處理,是個比較重要的類。
* 依賴項設定:Realm,SessionManager,CacheManager
*/
@Bean(name = "securityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(SystemAuthorizingRealm systemAuthorizingRealm,
DefaultWebSessionManager sessionManager, EhCacheManager examCacheManager) {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(systemAuthorizingRealm);
defaultWebSecurityManager.setSessionManager(sessionManager);
EhCacheManager ehCacheManager = new EhCacheManager();
ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
defaultWebSecurityManager.setCacheManager(examCacheManager);
return defaultWebSecurityManager;
}
2)配置SessionDAO
@Bean(name = "sessionDao")
public EnterpriseCacheSessionDAO sessionDao(){
EnterpriseCacheSessionDAO sessionDao = new EnterpriseCacheSessionDAO();
sessionDao.setActiveSessionsCacheName("shiro-activeSessionCache");
return sessionDao;
}
就這麼簡單!
