SpringBoot 整合Shiro 集成Ehcache緩存


簡介:用戶訪問資源時,每次都要進行權限認證,若去查詢數據庫,則會造成一定的壓力。由於實際情況下,用戶的權限一般不會發生改變,所以適合做緩存處理。單節點部署適合用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
name 緩存名稱,通常為緩存對象的類名
maxEntriesLocalHeap 在本地內存中最大緩存項數量,0代表不限制
maxEntriesLocalDisk 磁盤中最大對象數,0代表不限制
eternal 設置為true,表示對象永遠不會過期
timeToldleSeconds 對象處於空閑狀態的最大時間,0代表不限制,只有當eternal為false時才有效
timeToliveSeconds 對象能夠存活的最大時間,0代表不限制,只有當eternal為false時才有效
memoryStoreEvictionPolicy 內存回收策略(LRU、FIFO、LFU)
diskSpoolBufferSizeMB 磁盤緩存區的大小
 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配置文件詳解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM