本文参考张开套的《跟我学 Shiro》
授权也称作访问控制,即在应用中控制谁能够访问哪些资源(例如访问页面/编辑数据/页面操作等)。在授权中需要了解的几个关键对象:主体 Subject、资源 Resource、权限 Permission、角色 Role。
Shiro 支持三种方式的授权:
Subject subject = SecurityUtils.getSubject();
if (subject.hasRole("admin")){
// 具备 admin 权限
} else {
// 不具备
}
@RequiresRoles("admin")
public void hello() {
//有权限
}
Shiro 提供了 hasRole/hasAllRoles/hasRoles 用于判断用户是否拥有某个角色/某些权限;
Shiro 提供的 checkRole/checkRoles 用于判断用户没有某个角色/权限则会抛出 UnauthorizedException 异常。
这种方式的缺点就是如果很多地方进行了角色判断,但是有一天不需要了那么就需要修改相应的代码把所有相关的地方进行删除,这就是粗粒度造成的问题。
Shiro 提供了 isPermitted和isPermittedAll 用于判断用户是否拥有某个权限或者所有权限,也没有提供如 isPermittedAny 用于判断拥有某一个权限的接口。
这种方式的一般规则是“资源标识符:操作”,即是资源级别的粒度;这种方式的好处就是如果要修改基本都是一个资源级别的修改,不会对其他模块产生影响,力度小。但是实现起来稍微复杂点,需要维护"用户——角色",“角色——权限”之间的关系。
规则:资源标识符:操作:对象实例ID,即对哪个资源的实例可以进行什么操作。默认支持通配符权限字符串。
”:“ :表示资源/操作/实例的分割。
”,“ :逗号表示操作的分割。
”*“ :星号表示任意资源/操作/实例
subject().checkPermission("system:user:update");
ini 配置文件
role4=system:user:update,system:user:delete
Java 代码
subject().checkPermissions("system:user:update","system:user:delete")
上面的方式都可以简写:
role4="system:user:update,delete"
subject().checkPermission("system:user:update,delete");
ini 配置
role5="system:user:create,update,delete,view"
java 代码
subject().checkPermission("system:user:create,update,delete,view");
用户拥有增删改查的权限,可以简写为下面这样:
role5=system:user:*
subject().checkPermission("system:user:*");
role6=*:view
subject().checkPermission("user:view");
用户拥有所有资源的 view 所有权限,假设判断的权限是 system:user:view,可以这样写:
role5=*:*:view
ModularRealmAuthorizer 进行多 Realm 匹配流程:
如果 Realm 进行授权的话,应该继承 AuthorizingRealm ,它的流程是: