來源:https://www.jianshu.com/p/22bf52e09e4d
到這節為止,我們已經實現了身份驗證和權限驗證。但是,如果我們登錄之后多次訪問http://localhost:8080/userInfo/userDel
的話,會發現權限驗證會每次都執行一次。這是有問題的,因為像用戶的權限這些我們提供給shiro一次就夠了。
下面,我們開始給shiro添加緩存支持:
1.添加依賴
<!-- shiro ehcache --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.2</version> </dependency> <!-- 包含支持UI模版(Velocity,FreeMarker,JasperReports), 郵件服務, 腳本服務(JRuby), 緩存Cache(EHCache), 任務計划Scheduling(uartz)。 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency>
2.注入緩存
在com.example.demo.config.Shiro.ShiroConfiguration
中添加以下方法。
@Bean public EhCacheManager ehCacheManager() { System.out.println("ShiroConfiguration.getEhCacheManager()"); EhCacheManager ehCacheManager = new EhCacheManager(); ehCacheManager.setCacheManagerConfigFile("classpath:config/ehcache-shiro.xml"); return ehCacheManager; }
將緩存對象注入到SecurityManager
中:
@Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); securityManager.setCacheManager(ehCacheManager()); //注入緩存對象。 return securityManager; }
3.添加配置文件
在src/main/resouces/config中添加ehcache-shiro.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?> <ehcache name="es"> <diskStore path="java.io.tmpdir"/> <!-- name:緩存名稱。 maxElementsInMemory:緩存最大數目 maxElementsOnDisk:硬盤最大緩存個數。 eternal:對象是否永久有效,一但設置了,timeout將不起作用。 overflowToDisk:是否保存到磁盤,當系統當機時 timeToIdleSeconds:設置對象在失效前的允許閑置時間(單位:秒)。僅當eternal=false對象不是永久有效時使用,可選屬性,默認值是0,也就是可閑置時間無窮大。 timeToLiveSeconds:設置對象在失效前允許存活時間(單位:秒)。最大時間介於創建時間和失效時間之間。僅當eternal=false對象不是永久有效時使用,默認是0.,也就是對象存活時間無窮大。 diskPersistent:是否緩存虛擬機重啟期數據 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskSpoolBufferSizeMB:這個參數設置DiskStore(磁盤緩存)的緩存區大小。默認是30MB。每個Cache都應該有自己的一個緩沖區。 diskExpiryThreadIntervalSeconds:磁盤失效線程運行時間間隔,默認是120秒。 memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理內存。默認策略是LRU(最近最少使用)。你可以設置為FIFO(先進先出)或是LFU(較少使用)。 clearOnFlush:內存數量最大時是否清除。 memoryStoreEvictionPolicy: Ehcache的三種清空策略; FIFO,first in first out,這個是大家最熟的,先進先出。 LFU, Less Frequently Used,就是上面例子中使用的策略,直白一點就是講一直以來最少被使用的。如上面所講,緩存的元素有一個hit屬性,hit值最小的將會被清出緩存。 LRU,Least Recently Used,最近最少使用的,緩存的元素有一個時間戳,當緩存容量滿了,而又需要騰出地方來緩存新的元素的時候,那么現有緩存元素中時間戳離當前時間最遠的元素將被清出緩存。 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" /> <!-- 登錄記錄緩存鎖定10分鍾 --> <cache name="passwordRetryCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> </ehcache>
啟動項目,再多次訪問http://localhost:8080/userInfo/userDel
,這時候只會在后台打印一次配置權限的信息了,說明shiro緩存起了作用。
---------------------下面我們開始配置記住密碼-----------
1.在com.example.demo.config.Shiro.ShiroConfiguration
中加入下面兩個方法:
//cookie對象; @Bean public SimpleCookie rememberMeCookie() { System.out.println("ShiroConfiguration.rememberMeCookie()"); //這個參數是cookie的名稱,對應前端的checkbox的name = rememberMe SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); //<!-- 記住我cookie生效時間30天 ,單位秒;--> simpleCookie.setMaxAge(259200); return simpleCookie; } //cookie管理對象; @Bean public CookieRememberMeManager cookieRememberMeManager() { System.out.println("ShiroConfiguration.rememberMeManager()"); CookieRememberMeManager manager = new CookieRememberMeManager(); manager.setCookie(rememberMeCookie()); return manager; }
將rememberMeManager注入到SecurityManager中
@Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); securityManager.setCacheManager(ehCacheManager()); securityManager.setRememberMeManager(cookieRememberMeManager()); //注入rememberMeManager; return securityManager; }
在ShiroFilterFactoryBean
中添加記住我過濾器user
,添加user
過濾器的資源在記住我或認證之后就可以直接訪問了。
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); ... filterChainDefinitionMap.put("/index", "user"); filterChainDefinitionMap.put("/", "user"); ....
最后,在login.html頁面添加記住我單選框
<P><input type="checkbox" name="rememberMe" />記住我</P>
啟動項目,正常登錄后關閉瀏覽器,再打開瀏覽器輸入http://localhost:8080/index
,這時候就可以直接訪問index頁面,不需要再登錄了。
SpringBoot + Shiro (一)基礎工程搭建
SpringBoot + Shiro (二)身份校驗和角色設置
SpringBoot + Shiro (三)權限
SpringBoot + Shiro (四)緩存&記住密碼
SpringBoot + Shiro (五)驗證碼
最后,感謝幾位作者的文章解惑:
springboot整合shiro-登錄認證和權限管理
Spring Boot Shiro權限管理【從零開始學Spring Boot】
Spring boot 中使用Shiro
作者:憂郁的小碼仔
鏈接:https://www.jianshu.com/p/22bf52e09e4d
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。