第四章:基于角色和权限的权限认证
最后的工程结构:

-------------------------------------------------------
复制第三章的工程Shiro02, 改名Shiro03
-------------------------------------------------------
(1)基于角色的权限认证
一、加入Junit测试类, 修改pom.xml
<!-- 引入测试类Junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
二、封装第三章的测试代码,封装成一个工具类,方便日后使用
ShiroUtil.java
package com.java1234.common;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
/**
* 工具类
*/
public class ShiroUtil {
public static Subject login(String configFile, String userName, String password) {
// 读取shiro.ini文件, 获取SecurityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory(configFile);
// 获取securityManager实例
SecurityManager securityManager = factory.getInstance();
// 把securityManager绑定到SecurityUtils进行预处理
SecurityUtils.setSecurityManager(securityManager);
// 获取当前用户
Subject currentUser = SecurityUtils.getSubject();
// 创建用户名/密码的令牌Token
UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
// 身份认证, 通过源码知道这里有可能抛出异常
try {
currentUser.login(token);
System.out.println("身份认证成功!");
} catch (AuthenticationException e) {
e.printStackTrace();
System.out.println("身份认证失败!");
}
// 返回当前登录的用户
return currentUser;
}
}
三、创建基于角色的.ini配置文件(这里只做静态数据验证, 没有到数据库中取数)
shiro_role.ini, 固定写法,用户名 = 密码, 角色1, 角色2, 角色3 。。。
比如以下写法表示:java1234/123456这个用户同时拥有role1和role2的角色, 而jack/123这个用户只有role1这个角色
[users] java1234 = 123456, role1, role2 jack = 123, role1
四、测试代码, 创建com.java1234.shiro.RoleTest
package com.java1234.shiro;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
import com.java1234.common.ShiroUtil;
public class RoleTest {
@Test
public void testHasRole() {
Subject currentUser = ShiroUtil.login("classpath:shiro_role.ini", "jack", "123");
System.out.println(currentUser.hasRole("role1") ? "有role1这个角色" : "没有role1这个角色");
System.out.println(currentUser.hasRole("role2") ? "有role2这个角色" : "没有role2这个角色");
}
}
五、测试结果:
测试一:hasRole()

测试二:hasRoles()
boolean []result = currentUser.hasRoles(Arrays.asList("role1", "role2", "role3"));
System.out.println(result[0] ? "有role1这个角色" : "没有role1这个角色");
System.out.println(result[1] ? "有role2这个角色" : "没有role2这个角色");
System.out.println(result[2] ? "有role3这个角色" : "没有role3这个角色");
结果:

测试三:hasAllRoles()
boolean result = currentUser.hasAllRoles(Arrays.asList("role1", "role2"));
System.out.println(result ? "同时用拥有role1、role2" : "role1、role2角色不全有");
测试结果:

如果换成java1234/123456用户,测试结果:

测试四:checkRole(), 此方法没有返回值, 如果有指定的角色, 那么不报错, 如果在指定的角色中至少一个角色没有, 那么就会报错。
currentUser.checkRole("role1"); // currentUser.checkRole("role2");
结果:

currentUser.checkRole("role3");
结果:

测试五: checkRoles(), 判断集合, 如果指定的角色集合元素全部都有, 那么不会报错, 如果至少有一个没有, 那么就会报错!
currentUser.checkRoles(Arrays.asList("role1", "role2"));
结果:

currentUser.checkRoles(Arrays.asList("role1", "role2", "role3"));
结果:


--------------------------------------------
(2)基于权限的权限认证
1. shiro_permission.ini:
src/main/resources下创建基于权限认证的ini, 固定写法, 以下表示:
用户java1234/123456同时拥有role1和role2两个角色, jack/1234这个用户只有role1这个角色
role1这个角色只有user:select这个权限, role2这个角色同时拥有 user:add, user:update, user:delete 这三种权限。
[users] java1234 = 123456, role1, role2 jack = 1234, role1 [roles] role1 = user:select role2 = user:add, user:update, user:delete
2. PermissionTest.java
测试1:currentUser.isPermitted(String param)
package com.java1234.shiro;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
import com.java1234.common.ShiroUtil;
public class PermissionTest {
@Test
public void testIsPermitted() {
Subject currentUser = ShiroUtil.login("classpath:shiro_permission.ini", "java1234", "123456");
// 此方法一般不要使用接口参数, 使用字符串接收即可
System.out.println(currentUser.isPermitted("user:select") ? "有user:select这个权限" : "没有user:select这个权限");
System.out.println(currentUser.isPermitted("user:add") ? "有user:add这个权限" : "没有user:add这个权限");
System.out.println(currentUser.isPermitted("user:update") ? "有user:update这个权限" : "没有user:update这个权限");
System.out.println(currentUser.isPermitted("user:delete") ? "有user:delete这个权限" : "没有user:delete这个权限");
System.out.println(currentUser.isPermitted("user:XXX") ? "有user:XXX这个权限" : "没有user:XXX这个权限");
}
}
结果:

换成jack/1234用户,再测试:

测试2:currentUser.isPermitted(String ... params)
boolean []result = currentUser.isPermitted("user:select", "user:add", "user:update", "user:delete", "user:XXX");
System.out.println(result[0] ? "有user:select权限" : "没有user:select权限");
System.out.println(result[1] ? "有user:add权限" : "没有user:add权限");
System.out.println(result[2] ? "有user:update权限" : "没有user:update权限");
System.out.println(result[3] ? "有user:delete权限" : "没有user:delete权限");
System.out.println(result[4] ? "有user:XXX权限" : "没有user:XXX权限");
结果:

换成jack用户再测试:

测试3:currentUser.isPermittedAll(String ... params), 使用java1234/123456用户测试
boolean result1 = currentUser.isPermittedAll("user:select", "user:add");
boolean result2 = currentUser.isPermittedAll("user:select", "user:add", "user:XXX");
System.out.println(result1 ? "指定的权限全都有" : "指定的权限不全有");
System.out.println(result2 ? "指定的权限全都有" : "指定的权限不全有");
结果:

测试4:checkPermission(),判断单个权限, 其他方法类似,请查找 api 进行使用
/**
* 测试4:单个权限的判断
*/
currentUser.checkPermission("user:select"); // 如果有这个权限, 那么不会报错
currentUser.checkPermission("user:XXX"); // 没有这个权限, 会报错

浙公网安备 33010602011771号