SpringBoot整合Shiro+MD5+Salt+Redis實現認證和動態許可權管理|前後端分離(下)----築基後期
阿新 • • 發佈:2020-10-12
## 寫在前面
在上一篇文章[《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);
//配置不攔截路徑和攔截路徑,順序不能反