一、三种授权方式
1、编程式:通过写if/else授权代码块完成:
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”))
{
//有权限
}
else
{
//无权限
}
2、注解式:通过在执行的Java方法上放置相应的注解完成:
@RequiresRoles("admin")
public void hello()
{
//有权限
}
3、JSP/GSP标签:在JSP/GSP页面通过相应的标签完成:
< shiro: hasRole name = "admin" >
< !— 有权限 — >
< / shiro: hasRole >
二授权
** 1基于角色的访问控制(隐式角色)**
Shiro提供了hasRole/hasRole用于判断用户是否拥有某个角色/某些权限,checkRole/checkRoles和hasRole/hasAllRoles不同的地方是它在判断为假的情况下会抛出UnauthorizedException异常。具体用法如下:
//判断拥有角色:role1
Assert.assertTrue(subject().hasRole("role1"));
//判断拥有角色:role1 and role2
Assert.assertTrue(subject().hasAllRoles(Arrays.asList("role1", "role2")));
//判断拥有角色:role1 and role2 and !role3
boolean[] result = subject().hasRoles(Arrays.asList("role1", "role2", "role3"));
Assert.assertEquals(true, result[0]);
Assert.assertEquals(true, result[1]);
Assert.assertEquals(false, result[2]);
//断言拥有角色:role1
subject().checkRole("role1");
//断言拥有角色:role1 and role3 失败抛出异常
subject().checkRoles("role1", "role3");
总结:隐式角色缺点就是如果很多地方进行了角色判断,但是有一天不需要了那么就需要修改相应代码把所有相关的地方进行删除;这就是粗粒度造成的问题
3基于权限的访问控制(显示角色)
Shiro提供了isPermitted和isPermittedAll用于判断用户是否拥有某个权限或所有权限,checkPermission/checkPermissions和isPermitted和isPermittedAll不同的地方是它在判断为假的情况下会抛出UnauthorizedException异常。具体用法如下:
//判断拥有权限:user:create
Assert.assertTrue(subject().isPermitted("user:create"));
//判断拥有权限:user:update and user:delete
Assert.assertTrue(subject().isPermittedAll("user:update", "user:delete"));
//判断没有权限:user:view
Assert.assertFalse(subject().isPermitted("user:view"));
//断言拥有权限:user:create
subject().checkPermission("user:create");
//断言拥有权限:user:delete and user:update
subject().checkPermissions("user:delete", "user:update");
//断言拥有权限:user:view 失败抛出异常
subject().checkPermissions("user:view");
总结:这种方式的一般规则是“资源标识符:操作”,即是资源级别的粒度;这种方式的好处就是如果要修改基本都是一个资源级别的修改,不会对其他模块代码产生影响。
** 三Permission**
规则:“资源标识符:操作:对象实例ID” 即对哪个资源的哪个实例可以进行什么操作。
**1、单个资源单个权限 **
subject().checkPermissions("system:user:update");
2、单个资源多个权限
ini配置文件:
role41=system:user:update,system:user:delete
java代码:
subject().checkPermissions("system:user:update", "system:user:delete");
以上可以简写成如下所示:
ini配置文件:
role42="system:user:update,delete"
java代码:
subject().checkPermissions("system:user:update,delete");
通过“system:user:update,delete”验证"system:user:update, system:user:delete"是没问题的,但是反过来是规则不成立。
** 3、单个资源全部权限**
ini配置:
role51="system:user:create,update,delete,view"
Java代码:
subject().checkPermissions("system:user:create,delete,update:view");
以上可以简写成(推荐):
ini配置:
role52=system:user:*
Java代码:
subject().checkPermissions("system:user:*");
以上也可以简写成:
ini配置:
role53=system:user
Java代码 :
subject().checkPermissions("system:user")
通过“system:user:*”验证“system:user:create,delete,update:view”可以,但是反过来是不成立的
4、所有资源全部权限
ini配置:
role61=*:view
Java代码 :
subject().checkPermissions("user:view");
system:user:view对应role5=::view
5、实例级别的权限
单个实例单个权限
ini配置:
role71=user:view:1
Java代码 :
subject().checkPermissions("user:view:1");
单个实例多个权限
ini配置:
role72="user:update,delete:1"
Java代码 :
subject().checkPermissions("user:delete,update:1");
或
subject().checkPermissions("user:update:1", "user:delete:1");
所有实例单个权限
ini配置:
role74=user:auth:*
Java代码 :
subject().checkPermissions("user:auth:1", "user:auth:2");
所有实例所有权限
ini配置:
role75=user:*:*
Java代码 :
subject().checkPermissions("user:view:1", "user:auth:2");
Shiro对权限字符串缺失部分的处理
即可以匹配所有,不加可以进行前缀匹配;但是如“:view”不能匹配“system:user:view”,需要使用“::view”,即后缀匹配必须指定前缀(多个冒号就需要多个来匹配)。