簡介:用戶訪問資源時,每次都要進行權限認證,若去查詢數據庫,則會造成一定的壓力。由於實際情況下,用戶的權限一般不會發生改變,所以適合做緩存處理。單節點部署適合用ehcache緩存,若是分布式多節點部署,則應使用redis緩存
1. maven依賴
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.2</version>
</dependency>
2. 設置緩存管理器,此處開啟授權緩存,並加入securityManager中
/**
* 緩存管理器
*
* @return ehCacheManager
*/
@Bean
public EhCacheManager ehCacheManager() {
EhCacheManager ehCacheManager = new EhCacheManager();
ehCacheManager.setCacheManagerConfigFile("classpath:shiro-ehcache.xml");
return ehCacheManager;
}
/**
* token認證和授權驗證器
*
* @param ehCacheManager 緩存管理器
* @return jwtRealm
*/
@Bean
public JwtRealm jwtRealm(EhCacheManager ehCacheManager) {
JwtRealm jwtRealm = new JwtRealm();
jwtRealm.setCredentialsMatcher(new JwtCredentialsMatcher());
// 啟用授權緩存
jwtRealm.setAuthorizationCachingEnabled(true);
jwtRealm.setAuthorizationCacheName("authorizationCache");
jwtRealm.setCacheManager(ehCacheManager);
return jwtRealm;
}
3. 配置shiro-ehcache.xml文件
A. 參數配置詳解
cache |
|
||||||||||||||||
diskStore | 配置磁盤存儲的,可以存儲內存中驅除過來的元素,又可以在系統重啟的時候將內存中的緩存信息保存起來,供系統重新啟動后使用 |
B. 配置文件
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false" monitoring="autodetect" dynamicConfig="true">
<!-- 設置默認臨時文件路徑 --> <diskStore path="java.io.tmpdir"/>
<cache name="authorizationCache"
maxEntriesLocalHeap="1000"
maxEntriesLocalDisk="1000"
eternal="false"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="7200"
timeToLiveSeconds="28800"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
</cache>
</ehcache>
4. 若用戶的權限發生改變,該如何處理
A. 在jwtRelam中加入緩存清理方法
B. 在改變權限(修改角色中權限或者刪除角色)的代碼下,加入如下代碼
/**
* 清除權限緩存
*/
private void clearCache() {
DefaultWebSecurityManager webSecurityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
ModularRealmAuthorizer authorizer = (ModularRealmAuthorizer) webSecurityManager.getAuthorizer();
JwtRealm realm = (JwtRealm) authorizer.getRealms().iterator().next();
realm.clearCachedAuthorizationInfo();
}
5. 引用緩存時出現的錯誤
錯誤一:使用ehcache緩存后,程序啟動報錯,主要是緩存文件重名引起的
原因:這是由於自定義的緩存文件名與shiro自帶的緩存文件名classpath:org/apache/shiro/cache/ehcache/ehcache.xml重復
解決:修改文件名,如換為ehcache-shiro.xml即可
/**
* 緩存管理器
*
* @return ehCacheManager
*/
@Bean
public EhCacheManager ehCacheManager() {
EhCacheManager ehCacheManager = new EhCacheManager();
ehCacheManager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
return ehCacheManager;
}
錯誤二:緩存不生效,主要是cacheManager為null引起的
原因:多realm下,在SecurityManager下設置cacheManager不生效,即:securityManager.setCacheManager(cacheManager)
解決:需要在指定的realm中設置cacheManager,如:
/**
* token認證和授權驗證器
*
* @param ehCacheManager 緩存管理器
* @return jwtRealm
*/
@Bean
public JwtRealm jwtRealm(EhCacheManager ehCacheManager) {
JwtRealm jwtRealm = new JwtRealm();
jwtRealm.setCredentialsMatcher(new JwtCredentialsMatcher());
// 啟用授權緩存,注意cacheManager應寫在后面
jwtRealm.setAuthorizationCachingEnabled(true);
jwtRealm.setAuthorizationCacheName("authorizationCache");
jwtRealm.setCacheManager(ehCacheManager);
return jwtRealm;
}
錯誤三:使用ehcache緩存后,程序啟動報錯,主要是代碼順序引起的
原因:自定義realm中設置cacheManager時,若后設置緩存名,則無效,因為AuthenticatingRealm類中會默認設置個緩存名,這樣導致在緩存文件中找不到該名
解決:應如錯誤二中解決寫的代碼
可參考:ehcache2.x配置文件詳解