1. shiro默認自帶的realm和常見使用方法
- realm作用:Shiro 從 Realm 獲取安全數據
- 默認自帶的realm:idae查看realm繼承關系,有默認實現和自定義繼承的realm
- 兩個概念
- principal : 主體的標示,可以有多個,但是需要具有唯一性,常見的有用戶名,手機號,郵箱等
- credential:憑證, 一般就是密碼
- 所以一般我們說 principal + credential 就賬號 + 密碼
- 開發中,往往是自定義realm , 即集成 AuthorizingRealm,重寫AuthorizingRealm的getAuthorizationInfo方法


2. Shiro內置 ini realm 操作
在springboot的resources資源目錄下創建shiro.ini 配置文件,將下面內容復制進去
1 [users] 2 # 格式 name=password,role1,role2,..roleN 3 jack = 456, user 4 xdclass = 123, root, admin 5 # 格式 role=permission1,permission2...permissionN 也可以用通配符 6 # 下面配置user的權限為所有video:find,video:buy,如果需要配置video全部操作crud 則 user = video:*
7 [roles] 8 user = video:find,video:buy 9 # 下面定義了游客角色具有商品模塊的查詢,購買權限以及評論模塊的所有權限 10 visitor= good:find,good:buy,comment:*
11 # 'admin' role has all permissions, indicated by the wildcard '*'
12 admin = *
xdclass = 123, root, admin 表示,xdclass這個用戶密碼是123,具有 root 和admin兩個角色,
user = video:find,video:buy 表示,普通用戶角色具有視頻的查看,購買權限,
admin = * 表示admin角色具有所有的權限
測試代碼:
1 package net.xdclass.xdclassshiro; 2
3 import org.apache.shiro.SecurityUtils; 4 import org.apache.shiro.authc.UsernamePasswordToken; 5 import org.apache.shiro.config.IniSecurityManagerFactory; 6 import org.apache.shiro.mgt.DefaultSecurityManager; 7 import org.apache.shiro.mgt.SecurityManager; 8 import org.apache.shiro.realm.SimpleAccountRealm; 9 import org.apache.shiro.subject.Subject; 10 import org.apache.shiro.util.Factory; 11 import org.junit.Before; 12 import org.junit.Test; 13
14 /**
15 * iniRealm操作 16 */
17 public class QuicksStratTest5_2 { 18
19 @Test 20 public void testAuthentication() { 21 //通過配置文件創建SecurityManager工廠
22 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); 23 // 獲取SecurityManager實例
24 SecurityManager securityManager = factory.getInstance(); 25 //設置當前上下文
26 SecurityUtils.setSecurityManager(securityManager); 27
28 //獲取當前subject(application應用的user)
29 Subject subject = SecurityUtils.getSubject(); 30 // 模擬用戶輸入
31 UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("jack","456"); 32 // 33 subject.login(usernamePasswordToken); 34 System.out.println("認證結果(是否已授權):" + subject.isAuthenticated()); //認證結果(是否已授權):true 35 //最終調用的是org.apache.shiro.authz.ModularRealmAuthorizer.hasRole方法
36 System.out.println("是否有對應的角色:" + subject.hasRole("root")); //是否有對應的角色:false 37 //獲取登錄 賬號
38 System.out.println("getPrincipal():" + subject.getPrincipal()); //getPrincipal():jack 39 //校驗角色,沒有返回值,校驗不通過,直接跑出異常
40 subject.checkRole("user"); 41 // user jack有video的find權限,執行通過
42 subject.checkPermission("video:find"); 43 // 是否有video:find權限:true
44 System.out.println("是否有video:find權限:" + subject.isPermitted("video:find")); 45 // 是否有video:delete權限:false
46 System.out.println("是否有video:delete權限:" + subject.isPermitted("video:delete")); 47 //user jack沒有video的刪除權限,執行會報錯:org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [video:delete]
48 subject.checkPermission("video:delete"); 49 // subject.logout(); 50 // System.out.println("logout后認證結果:" + subject.isAuthenticated());
51 } 52
53 @Test 54 public void testAuthentication2() { 55 //通過配置文件創建SecurityManager工廠
56 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); 57 // 獲取SecurityManager實例
58 SecurityManager securityManager = factory.getInstance(); 59 //設置當前上下文
60 SecurityUtils.setSecurityManager(securityManager); 61 //獲取當前subject(application應用的user)
62 Subject subject = SecurityUtils.getSubject(); 63 // 模擬用戶輸入
64 UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("xdclass","123"); 65 subject.login(usernamePasswordToken); 66 System.out.println("認證結果(是否已授權):" + subject.isAuthenticated()); // 認證結果(是否已授權):true 67 //最終調用的是org.apache.shiro.authz.ModularRealmAuthorizer.hasRole方法
68 System.out.println("是否有admin角色:" + subject.hasRole("admin")); //是否有admin角色:true
69 System.out.println("是否有root角色:" + subject.hasRole("root")); //是否有root角色:true 70 //獲取登錄 賬號
71 System.out.println("getPrincipal():" + subject.getPrincipal()); //getPrincipal():xdclass 72 // admin角色具有所有權限
73 subject.checkPermission("video:find"); 74 // 是否有video:find權限:true
75 System.out.println("是否有video:find權限:" + subject.isPermitted("video:find")); //是否有video:find權限:true 76 // 是否有video:delete權限:true
77 System.out.println("是否有video:delete權限:" + subject.isPermitted("video:delete")); // 是否有video:find權限:true 78 // 結果為true,如果subject.checkPermission校驗不通過,則拋出異常
79 subject.checkPermission("video:delete"); 80 } 81 }
