
正文
shiro权限框架(四)
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
4.1授权方式
Shiro 支持三种方式的授权
编程式:通过写 if/else 授权代码块完成:
Subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有权限
} else {
//无权限
}
注解式:通过在执行的 Java 方法上放置相应的注解完成:
@RequiresRoles("admin")
public void hello() {
//有权限
}
没有权限将抛出相应的异常;
JSP/GSP 标签:在 JSP/GSP 页面通过相应的标签完成:
<shiro:hasRole name="admin"> <!— 有权限 —> </shiro:hasRole>
注:本文在后台是以注解的方式
4.2 permission
1. 字符串通配符权限
规则:“资源标识符:操作:对象实例 ID” 即对哪个资源的哪个实例可以进行什么操作。其默认支持通配符权限字符串,“:”表示资源/操作/实例的分割;“,”表示操作的分割;“*”表示任意资源/操作/实例。
如:单个资源单个权限
@RequiresPermissions(value="system:user:save")
用户拥有资源“system:user”的“update”权限。
单个资源多个权限
@RequiresPermissions(value={"system:user:save","system:user:update"},logical=Logical.OR)
用户拥有资源“system:user”中的“save”或者“update”权限其中一个就可以通过;不加“Logical.OR”则表示两个权限同时满足才可以通过。
单个资源全部权限
@RequiresPermissions(value="system:user:* ")
以资源“system:user”下有权限create,update,delete三个权限为例;system:user:*表示用户拥有这三个权限。
注:shiro注解后续会讲解。
4.3授权流程
流程如下:
1、首先调用 Subject.isPermitted*/hasRole*接口,其会委托给 SecurityManager,而SecurityManager 接着会委托给 Authorizer;
2、Authorizer 是真正的授权者,如果我们调用如 isPermitted(“user:view”),其首先会通过PermissionResolver 把字符串转换成相应的 Permission 实例;
3、在进行授权之前,其会调用相应的 Realm 获取 Subject 相应的角色/权限用于匹配传入的角色/权限;
4、Authorizer 会判断 Realm 的角色/权限是否和传入的匹配,如果有多个 Realm,会委托给ModularRealmAuthorizer 进行循环判断,如果匹配如 isPermitted*/hasRole*会返回 true,否则返回 false 表示授权失败。
ModularRealmAuthorizer 进行多 Realm 匹配流程:
1、首先检查相应的 Realm 是否实现了实现了 Authorizer;
2、如果实现了 Authorizer,那么接着调用其相应的 isPermitted*/hasRole*接口进行匹配;
3、如果有一个 Realm 匹配那么将返回 true,否则返回 false。如果 Realm 进行授权的话,应该继承 AuthorizingRealm,其流程是:
1.1、如果调用 hasRole*,则直接获取 AuthorizationInfo.getRoles()与传入的角色比较即可;
1.2、首先如果调用如 isPermitted(“user:view”),首先通过 PermissionResolver 将权限字符串转换成相应的 Permission 实例,默认使用 WildcardPermissionResolver,即转换为通配符的WildcardPermission;
2 、 通 过 AuthorizationInfo.getObjectPermissions() 得 到 Permission 实 例 集 合 ; 通 过AuthorizationInfo. getStringPermissions()得到字符串集合并通过 PermissionResolver 解析为Permission 实例;然后获取用户的角色,并通过 RolePermissionResolver 解析角色对应的权限集合(默认没有实现,可以自己提供);
3、接着调用 Permission. implies(Permission p)逐个与传入的权限比较,如果有匹配的则返回true,否则 false。







