1. 程式人生 > >我的shiro之旅: 九 shiro 清理快取的許可權資訊

我的shiro之旅: 九 shiro 清理快取的許可權資訊

部落格已移至 http://blog.gogl.top

在文章八講到了shiro快取許可權資訊然後達到共享目的,不過存在一個問題,當用戶的許可權發生改變的時候,需要使用者重新登入,從新快取使用者許可權資訊。這篇文章將介紹在改變使用者的許可權時,如何清理使用者的許可權。我這裡寫了一個幫助類,先貼也程式碼。

package com.concom.security.infrastructure.helper;

import java.io.Serializable;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.concom.security.infrastructure.shiro.ShiroRealm;
import com.concom.security.infrastructure.shiro.cache.ShiroCacheManager;

/**
 * @author Dylan
 * @time 2014年1月8日
 */
public class ShiroAuthorizationHelper {

	/**
	 * 
	 */
	private static ShiroCacheManager cacheManager;
	
	private static Logger log = LoggerFactory.getLogger(ShiroAuthorizationHelper.class);
	
	
	/**
	 * 清除使用者的授權資訊
	 * @param username
	 */
	public static void clearAuthorizationInfo(String username){
		if(log.isDebugEnabled()){
			log.debug("clear the " + username + " authorizationInfo");
		}
		//ShiroCasRealm.authorizationCache 為shiro自義cache名(shiroCasRealm為我們定義的reaml類的類名)
		Cache<Object, Object> cache = cacheManager.getCache(ShiroRealm.REALM_NAME+".authorizationCache");
		cache.remove(username);
	}
	
	/**
	 * 清除當前使用者的授權資訊
	 */
	public static void clearAuthorizationInfo(){
		if(SecurityUtils.getSubject().isAuthenticated()){
			clearAuthorizationInfo(ShiroSecurityHelper.getCurrentUsername());
		}
	}
	
	/**清除session(認證資訊)
	 * @param JSESSIONID
	 */
	public static void clearAuthenticationInfo(Serializable JSESSIONID){
		if(log.isDebugEnabled()){
			log.debug("clear the session " + JSESSIONID);
		}
		//shiro-activeSessionCache 為shiro自義cache名,該名在org.apache.shiro.session.mgt.eis.CachingSessionDAO抽象類中定義
		//如果要改變此名,可以將名稱注入到sessionDao中,例如注入到CachingSessionDAO的子類EnterpriseCacheSessionDAO類中
		Cache<Object, Object> cache = cacheManager.getCache("shiro-activeSessionCache");
		cache.remove(JSESSIONID);
	}

	public static ShiroCacheManager getCacheManager() {
		return cacheManager;
	}

	public static void setCacheManager(ShiroCacheManager cacheManager) {
		ShiroAuthorizationHelper.cacheManager = cacheManager;
	}
	
	
}

上面的ShiroAuthorizationHelper通過spring把ShiroCacheManager注入了進來,並提供了兩個靜態方法。分別是clearAuthorizationInfo(String username)方法,根據使用者名稱清空使用者許可權資訊,clearAuthenticationInfo(String JSESSIONID),根據sessionId來清除session。上篇文章有提到過ShiroCasRealm.authorizationCache和shiro-activeSessionCache這兩個Cache的名稱,在這裡不再重複。如果有不清楚的,請看回上一篇文章。

因為ShiroAuthorizationHelper是個幫助類,方法是靜態方法,可以利用spring來把物件注入到幫助類中。新增如下配置。

        <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
		<property name="staticMethod" value="com.concom.security.infrastructure.helper.ShiroAuthorizationHelper.setCacheManager" />
		<property name="arguments" ref="shiroCacheManager"/>
	</bean>

將shiroCacheManager注入到ShiroAuthorizationHelper的靜態方法中。這樣,通過這個工具類,就可以直接呼叫它的靜態方法去清理快取。當權限快取被清理後,shiro需要授權時,查詢快取沒有許可權資訊,將會再次呼叫realm的doGetAuthorizationInfo去load使用者的許可權,再次放入快取中。realm的實現在文章五中有介紹,這裡不再重複,不清楚的可以看看文章五和文章二。這篇文章也講到這裡。謝謝。