这一节着重介绍了 Shiro 中权限的字符串比较规则是 Shiro 自定义的通配符匹配规则。
在 Shiro 中默认对角色和权限的定义和解析都是通过字符串来完成的。对于字符串的说明,在 Shiro 的官方文档和张开涛老师的博客上都有详细的说明。
我们主要还是以例子的方式来说明如何使用。我们在 Shiro 的核心配置文件 shiro.ini 中写到的:
[users]
liwei=123456,role1,role2
在 Shiro 中默认对角色和权限的定义和解析都是通过字符串的操作来完成的。这个配置文件表明:在安全数据源中有一个用户叫 liwei,密码是 123456,liwei 这个用户拥有的角色是 role1 和 role2。
我们再来看一个例子,我们在 Shiro 的核心配置文件 shiro.ini 中写到:
[users]
liwei=123456,role1,role2
zhouguang=666666,role1
[roles]
role1=user:select
role2=user:add,user:update,user:delete
说明:在安全数据源中有一个用户叫 liwei,密码是 123456,liwei 这个用户拥有的角色是 role1 和 role2。“role1”、“role2” 是表示角色定义的字符串,具体角色拥有哪些权限,声明在 [roles] 节点下面。
对于角色具体有哪些权限,定义在角色名称的右边,不同的权限用逗号分开。
接下来,我们通过代码来展示 Shiro 是如何进行角色和权限的“验证”的。
public class PermissionTest {
@Test
public void testIsPermitted(){
Subject currentUser = ShiroUtil.login("shiro.ini","liwei","123456");
boolean b1 = currentUser.isPermitted("user:select");
System.out.println(b1);
boolean[] results = currentUser.isPermitted("user:select","user:update","user:delete","user:insert");
System.out.println(results[0]);
System.out.println(results[1]);
System.out.println(results[2]);
System.out.println(results[3]);
boolean b2 =currentUser.isPermittedAll("user:select","user:update","user:delete");
System.out.println(b2);
}
@Test
public void testCheckPermitted(){
Subject currentUser = ShiroUtil.login("shiro.ini","liwei","123456");
currentUser.checkPermission("user:select");
// currentUser.checkPermission("user:update");
currentUser.checkPermissions("user:select","user:update","user:delete");
}
}
说明:上面的代码使用 isPermitted()
方法判断这个登录的用户是否具有参数字符串所表示的权限,返回一个 boolean 类型的值。checkPermission()
和 isPermitted()
方法的功能是类似的,区别在于如果这个登录的用户不具有参数字符串所表示的权限时,程序将抛出异常。
类似地,hasRole()
和 checkRole()
方法也有类似的作用,在这里就不多做解释了。
那么,Shiro 的这种基于字符串的角色和权限验证方式能不能修改呢,这是完全可以的,这就体现了 Shiro 和绝大多数框架的一个设计风格和原则,你可以用它的东西,也可以扩展它的东西。
不过我们首先要知道 Shiro 默认对于角色和权限判断的流程是什么。
先来说权限,我们要认识一个很重要的类 WildcardPermission
,这是基于通配符的一个权限匹配接口,下面的两种写法是等价的:
subject().checkPermission("menu:view:1");
与
subject().checkPermission(new WildcardPermission("menu:view:1"));
等价。
这说明,Shiro 默认使用 WildcardPermission
这个类进行权限匹配。
其次,我们还要知道 PermissionResolver
这个接口,它用于解析权限字符串到 Permission 实例。具体的例子,我们到下小节讲。