1. 添加依赖
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-web</artifactId> 4 </dependency> 5 <dependency> 6 <groupId>mysql</groupId> 7 <artifactId>mysql-connector-java</artifactId> 8 </dependency> 9 <dependency> 10 <groupId>org.springframework.boot</groupId> 11 <artifactId>spring-boot-starter-test</artifactId> 12 <scope>test</scope> 13 </dependency> 14 <dependency> 15 <groupId>org.apache.shiro</groupId> 16 <artifactId>shiro-spring</artifactId> 17 <version>1.4.0</version> 18 </dependency> 19
2. Shiro认证和授权流程
2.1 常用API:
//是否有对应的角色 subject.hasRole("root") //获取subject名 subject.getPrincipal() //检查是否有对应的角色,无返回值,直接在SecurityManager里面进行判断 subject.checkRole("admin") //检查是否有对应的角色 subject.hasRole("admin") //退出登录 subject.logout();
2.2 shiro认证流程:
测试代码:
1 package net.xdclass.xdclassshiro; 2 3 import org.apache.shiro.SecurityUtils; 4 import org.apache.shiro.authc.UsernamePasswordToken; 5 import org.apache.shiro.mgt.DefaultSecurityManager; 6 import org.apache.shiro.realm.SimpleAccountRealm; 7 import org.apache.shiro.subject.Subject; 8 import org.junit.Before; 9 import org.junit.Test; 10 11 /** 12 * shiro认证过程: 13 * 1.构造SecurityManager环境 14 * 2.调用Subject.login()执行认证 15 * 3.SecurityManager进行认证 16 * 4.Authenticator执行 认证 17 * 5.根据realm进行验证 18 */ 19 public class QuicksStratTest { 20 21 /** 22 * accountRealm 相当于数据库的作用 23 */ 24 private SimpleAccountRealm accountRealm = new SimpleAccountRealm(); 25 26 private DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(); 27 28 @Before 29 public void init() { 30 //初始化数据源 31 accountRealm.addAccount("lch", "123"); 32 accountRealm.addAccount("jack", "345"); 33 //构建环境 34 defaultSecurityManager.setRealm(accountRealm); 35 36 } 37 38 @Test 39 public void testAuthentication() { 40 //设置当前上下文 41 SecurityUtils.setSecurityManager(defaultSecurityManager); 42 //设置当前subject(application应用的user) 43 Subject subject = SecurityUtils.getSubject(); 44 //模拟用户输入 45 UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("lch", "123"); 46 // 实际是调用securityManager的login方法 Subject subject = this.securityManager.login(this, token); 47 subject.login(usernamePasswordToken); 48 System.out.println("认证结果(是否已授权):" + subject.isAuthenticated()); // 打印true 49 50 51 } 52 }
上面这个login方法里面 ,会调用认证器对 usernamePasswordToken 中的用户信息进行认证
2.3 shiro授权流程:
测试代码:
1 package net.xdclass.xdclassshiro; 2 3 import org.apache.shiro.SecurityUtils; 4 import org.apache.shiro.authc.UsernamePasswordToken; 5 import org.apache.shiro.mgt.DefaultSecurityManager; 6 import org.apache.shiro.realm.SimpleAccountRealm; 7 import org.apache.shiro.subject.Subject; 8 import org.junit.Before; 9 import org.junit.Test; 10 11 /** 12 * shiro授权过程及常用API: 13 * 1.构造SecurityManager环境 14 * 2.Subject执行授权 15 * 3.SecurityManager进行认证授权 16 * 4.Authenticator执行授权 17 * 5.根据realm进行授权验证 18 */ 19 public class QuicksStratTest2 { 20 21 /** 22 * accountRealm 相当于数据库的作用 23 */ 24 private SimpleAccountRealm accountRealm = new SimpleAccountRealm(); 25 26 private DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(); 27 28 @Before 29 public void init() { 30 //初始化数据源,入参加入用户角色 31 accountRealm.addAccount("lch", "123","root","admin"); 32 accountRealm.addAccount("jack", "345","user"); 33 //构建环境 34 defaultSecurityManager.setRealm(accountRealm); 35 } 36 37 @Test 38 public void testAuthentication() { 39 //设置当前上下文 40 SecurityUtils.setSecurityManager(defaultSecurityManager); 41 //设置当前subject(application应用的user) 42 Subject subject = SecurityUtils.getSubject(); 43 //模拟用户输入 44 UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("lch", "123"); 45 // 实际是调用securityManager的login方法 Subject subject = this.securityManager.login(this, token); 46 subject.login(usernamePasswordToken); 47 48 System.out.println("认证结果(是否已授权):" + subject.isAuthenticated()); // 结果:true 49 //最终调用的是org.apache.shiro.authz.ModularRealmAuthorizer.hasRole方法 50 System.out.println("是否有对应的角色:" + subject.hasRole("root")); // 结果:true 51 //获取登录 账号 52 System.out.println("getPrincipal():" + subject.getPrincipal()); // getPrincipal():lch 53 subject.logout(); 54 System.out.println("logout后认证结果:" + subject.isAuthenticated()); //logout后认证结果:false 55 56 57 } 58 }
subject.hasRole()方法,实际上是调用SecurityManager的hasRole方法进行权限校验:
SecurityManager的hasRole方法,又是调用authorizer的hasRole方法去校验,
它有三个实现类:
测试代码中使用的 SimpleAccountRealm 是继承自 AuthorizingRealm,所以这里我们进入第一个实现类AuthorizingRealm 里面,发现它的授权逻辑如下: