1. 程式人生 > >SpringBoot整合Shiro+MD5+Salt+Redis實現認證和動態許可權管理|前後端分離(下)----築基後期

SpringBoot整合Shiro+MD5+Salt+Redis實現認證和動態許可權管理|前後端分離(下)----築基後期

## 寫在前面 在上一篇文章[《SpringBoot整合Shiro+MD5+Salt+Redis實現認證和動態許可權管理(上)----築基中期》](https://juejin.im/post/6880872387416588295)當中,我們初步實現了SpringBoot整合Shiro實現認證和授權。 在這篇文章當中,我將帶領大家一起完善這個Demo。當然,在這之前我們需要了解一些知識點。 本片文章與上一篇[《SpringBoot整合Shiro+MD5+Salt+Redis實現認證和動態許可權管理(上)----築基中期》](https://juejin.im/post/6880872387416588295) 緊密相連,建議您先閱讀上一篇文章,再閱讀本文。 ## 知識點補充 ### Shiro快取 #### 流程分析 在原來的專案當中,由於沒有配置快取,因此每次需要驗證當前主體有沒有訪問許可權時,都會去查詢資料庫。由於許可權資料是典型的讀多寫少的資料,因此,我們應該要對其加入快取的支援。 當我們加入快取後,shiro在做鑑權時先去快取裡查詢相關資料,快取裡沒有,則查詢資料庫並將查到的資料寫入快取,下次再查時就能從快取當中獲取資料,而不是從資料庫中獲取。這樣就能改善我們的應用的效能。 接下來,我們去實現shiro的快取管理部分。 ### Shiro會話機制 Shiro 提供了完整的企業級會話管理功能,不依賴於底層容器(如 web 容器 tomcat),不管 JavaSE 還是 JavaEE 環境都可以使用,提供了會話管理、會話事件監聽、會話儲存 / 持久化、容器無關的叢集、失效 / 過期支援、對 Web 的透明支援、SSO 單點登入的支援等特性。 我們將使用 Shiro 的會話管理來接管我們應用的web會話,並通過Redis來儲存會話資訊。 ## 整合步驟 ### 新增快取 #### CacheManager 在Shiro當中,它提供了CacheManager這個類來做快取管理。 #### 使用Shiro預設的EhCache實現 在shiro當中,預設使用的是EhCache快取框架。EhCache 是一個純Java的程序內快取框架,具有快速、精幹等特點。關於更多EhCache的內容,同學們可以自行百度瞭解,這裡不做過多介紹。 ##### 引入shiro-EhCache依賴 ```xml ``` 在SpringBoot整合Redis的過程中,還要注意版本匹配的問題,不然有可能報方法未找到的異常。 ##### 在ShiroConfig中新增快取配置 ```java private void enableCache(MySQLRealm realm){ //開啟全域性快取配置 realm.setCachingEnabled(true); //開啟認證快取配置 realm.setAuthenticationCachingEnabled(true); //開啟授權快取配置 realm.setAuthorizationCachingEnabled(true); //為了方便操作,我們給快取起個名字 realm.setAuthenticationCacheName("authcCache"); realm.setAuthorizationCacheName("authzCache"); //注入快取實現 realm.setCacheManager(new EhCacheManager()); } ``` 然後再在getRealm中呼叫這個方法即可。 **提示**:在這個實現當中,只是實現了本地的快取。也就是說快取的資料同應用一樣共用一臺機器的記憶體。如果伺服器發生宕機或意外停電,那麼快取資料也將不復存在。當然你也可通過cacheManager.setCacheManagerConfigFile()方法給予快取更多的配置。 接下來我們將通過Redis快取我們的許可權資料 #### 使用Redis實現 ##### 新增依賴 ```xml ``` ##### 配置redis 在application.yml中新增redis的相關配置 ```yaml spring: redis: host: 127.0.0.1 port: 6379 password: hewenping timeout: 3000 jedis: pool: min-idle: 5 max-active: 20 max-idle: 15 ``` 修改ShiroConfig配置類,新增shiro-redis外掛配置 ```java /**shiro配置類 * @author 賴柄灃 [email protected] * @version 1.0 * @date 2020/10/6 9:11 */ @Configuration public class ShiroConfig { private static final String CACHE_KEY = "shiro:cache:"; private static final String SESSION_KEY = "shiro:session:"; private static final int EXPIRE = 18000; @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private int timeout; @Value("${spring.redis.password}") private String password; @Value("${spring.redis.jedis.pool.min-idle}") private int minIdle; @Value("${spring.redis.jedis.pool.max-idle}") private int maxIdle; @Value("${spring.redis.jedis.pool.max-active}") private int maxActive; @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(org.apache.shiro.mgt.SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } /** * 建立ShiroFilter攔截器 * @return ShiroFilterFactoryBean */ @Bean(name = "shiroFilterFactoryBean") public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //配置不攔截路徑和攔截路徑,順序不能反