【Shiro】4.Springboot整合Shiro

陆陆无为而治者發表於2024-10-07

https://blog.csdn.net/sco5282/article/details/134016549

前面已經學習了Shiro快速入門快取 。現在假定實際業務中需要完成以下功能:

1. 包含頁面登入和首頁。

2. 登入時需要連線資料庫,完成登入認證和授權。

3. 登入時,密碼需要加密。

4. 登入和授權資訊能夠快取。

5. 授權演示兩種模式,基於角色授權和基於資源授權。

前提條件

因為這裡主要學習shiro,所以與shiro不相干的步驟和準備,儘量簡單表示。

1. 新建SpringBoot的Web專案,並新建頁面index.html(主頁,對應路由ip:介面/index)和login.html(登入頁面,對應路由ip:介面/login)。

2. mysql資料庫包含使用者、角色以及授權的表格(如下圖)。這些表格的方法已在SpringBoot結合(Mybatis或Mybatisplus)形成基礎的查詢方法,我們演示的時候只要呼叫以上方法即可。

引入依賴

這裡我們需要引用需要的shiro和redis依賴項。

 1 <dependency>
 2     <groupId>org.apache.shiro</groupId>
 3     <artifactId>shiro-spring</artifactId>
 4     <version>1.13.0</version>
 5 </dependency>
 6 <!-- Redis 快取-->
 7 <dependency>
 8     <groupId>org.springframework.boot</groupId>
 9     <artifactId>spring-boot-starter-data-redis</artifactId>
10     <version>2.5.15</version>
11 </dependency>
12 <dependency>
13     <groupId>org.springframework.data</groupId>
14     <artifactId>spring-data-redis</artifactId>
15     <version>2.5.12</version>
16 </dependency>

新增Shiro配置類

根據已學過的知識,新增配置類ShiroConfiguratin

 1 @Configuration
 2 public class ShiroConfiguratin {
 3     @Autowired
 4     private RedisTemplate redisTemplate;
 5 
 6     // 1.建立 shiroFilter,負責攔截所有請求
 7     @Bean
 8     public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
 9         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
10         //給filter設定安全管理器
11         shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
12         //配置系統受限資源
13         //配置系統公共資源
14         Map<String,String> map = new HashMap<>();
15         // authc 請求這個資源需要認證和授權
16         map.put("/index", "authc");
17         //預設認證介面路徑
18         shiroFilterFactoryBean.setLoginUrl("/login");
19         shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
20         return shiroFilterFactoryBean;
21     }
22 
23     //2.建立安全管理器
24     @Bean
25     public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
26         DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
27         //給安全管理器設定
28         defaultWebSecurityManager.setRealm(realm);
29         return defaultWebSecurityManager;
30     }
31 
32     /**
33      * 3.建立自定義realm
34      * @return
35      */
36     @Bean
37     public Realm getRealm(){
38         SysUserRealm sysUserRealm = new SysUserRealm();
39         // 設定快取管理器
40         sysUserRealm.setCacheManager(new RedisCacheManage(redisTemplate)); // 自定義Redis資料庫快取方法
41         // 開啟全域性快取
42         sysUserRealm.setCachingEnabled(true);
43         // 開啟認證快取並指定快取名稱
44         sysUserRealm.setAuthenticationCachingEnabled(true);
45         sysUserRealm.setAuthenticationCacheName("authenicationCache");
46         // 開啟快取授權並指定快取名稱
47         sysUserRealm.setAuthorizationCachingEnabled(true);
48         sysUserRealm.setAuthorizationCacheName("authenicationCache");
49         return sysUserRealm;
50     }
51 }

這裡的配置類完成以下功能。

  • 完成攔截請求(登入index頁面前,需要經過認證和授權認證和授權頁面(login))
  • 建立安全管理(新增域管理器)
  • 設定自定義域,完成快取的設定(使用Redis快取,詳見:https://www.cnblogs.com/luyj00436/p/18446712)。

根據之前學到的知識,自定義域完成了認證和授權 SysUserRealm

 1 public class SysUserRealm extends AuthorizingRealm {
 2     @Autowired
 3     private SysUserMapper sysUserMapper;        // 使用者查詢
 4     /**
 5      * 授權
 6      * @param principals the primary identifying principals of the AuthorizationInfo that should be retrieved.
 7      * @return
 8      */
 9     @Override
10     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
11         // 從系統返回的身份資訊集合中獲取主身份資訊(使用者名稱)
12         String primaryPrincipal = (String) principals.getPrimaryPrincipal();
13         // TODO 根據使用者名稱獲取當前使用者的角色資訊,以及許可權資訊
14         SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
15         // 將資料庫中查詢到的角色資訊賦值給許可權物件 
16         simpleAuthorizationInfo.addRole("admin");
17         simpleAuthorizationInfo.addRole("user");
18         // 將資料庫中查詢許可權資訊賦值給許可權物件
19         simpleAuthorizationInfo.addStringPermission("user:*:01");
20         simpleAuthorizationInfo.addStringPermission("product:create");
21         return simpleAuthorizationInfo;
22     }
23 
24     /**
25      * 認證
26      * @param token the authentication token containing the user's principal and credentials.
27      * @return
28      * @throws AuthenticationException
29      */
30     @Override
31     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
32         // 在token中獲取使用者名稱
33         String principal = (String) token.getPrincipal();   // 獲取使用者名稱
34         // 根據獲取到的使用者名稱查詢資料(這裡用id代替)
35         SysUser resUser = sysUserMapper.selectById(1);
36         if(principal.equals(resUser.getUsername())){
37             // 引數說明:使用者|密碼|當前realm的名字
38             return new SimpleAuthenticationInfo(principal,resUser.getPassword(), this.getName() );
39         }
40         return null;
41     }
42 }

相關文章