Shiro 学习笔记(Authorization)
Shiro Authorization授权
一.授权
访问控制,即在应用中控制谁能访问哪些资源
有三个核心要素:
1)权限(permission):即操作资源的权利,仅仅声明对某个资源可以进行什么样的操作,比如访问某个页面,以及对某个模块的数据的添加,修改,删除,查看的权利;
在Shiro中代表粒度(granularity)最小的(原子性)的安全策略,还可以细化为:
资源:对用户信息进行修改;
实例:对用户信息A进行修改;
属性:对用户信息A中的姓名进行修改
2)角色(role):指的是用户担任的的角色,一个角色可以有多个权限,通常将Role分配给User,User有没有操作权限归因于Role;
Role有两种类型,分别是隐式(implicity)和显示(explicity) :
Implicity Roles:根据某个角色判断是否对资源有操作权限,粒度较粗;
Explicity Roles:关注是否有进行该操作的权限,角色只是聚合了权限,用户拥有某角色;
也可以理解为基于角色的访问权限控制与基于资源的访问权限控制
一般更建议使用基于资源的访问权限控制
3)用户(user):在Shiro 中,代表访问系统的用户,即Subject认证主体
可以根据角色或者权限决定是否允许用户执行某个操作,可以直接将权限分配给用户,也可以将权限分配给角色再将角色分配给用户,或者我们也可以根据具体的需求再加一个层级
二.授权方式
1.编码方式 if(){}else{}
1)基于角色的访问控制 相关API
实现示例:
Subject currentUser = SecurityUtils.getSubject(); if (currentUser.hasRole("administrator")) { //show the admin button or do administrator's things } else { //don't show the button? Grey it out? or others... }
Subject currentUser = SecurityUtils.getSubject(); currentUser.checkRole("bankTeller"); openBankAccount();
2)基于资源的访问控制 相关API
2.注解方式
在方法上添加注解,如下:
@RequiresAuthentication 要求当前 Subject 已经在当前的 session 中被验证通过才能被注解的类/实例/方法访问或 调用;
@RequiresGuest Subject必须是在之前的 session 中没有被验证或记住 才能被注解的类/实例/方法访问或调用;
@RequiresPermissions 要求当前的 Subject 被允许一个或多个权限,以便执行注解的方法
@RequiresRoles 要求当前的 Subject 拥有所有指定的角色
@RequiresUser 需要已通过认证
示例:
@RequiresRoles({"admin","leader"}) public void deleteUsers(){ //... }
3.页面标签:JSP/GSP 页面通过相应的标签完成
二、授权过程
1)应用程序或框架代码调用任何 Subject(通常是 DelegatingSubject(或子类)) 的 hasRole*, checkRole*, isPermitted*, 或者 checkPermission*方法的变体,传递任何所需的权限或角色代表;
2)获取所有的principals并将权限验证的工作委托给securityManager;
3)securityManager直接将工作委托给其内部的authorizer;
4)Realm的权限验证方法被调用,从权限信息中获取权限集合,循环调用其implies方法判断是否拥有权限。
注意:PermissionResolver 主要用于将以String表示的权限转为Permission实例
RolePermissionResolver 将角色String解析为Permission对象集合
AuthorizingRealm的constructor中:
如果传入的权限是以String形式表示,则需要一个resolvePermission的过程;此处会用到PermissionResolver将字符串转为Permission实例;如果Realm的权限验证方法出现异常,异常将作为AuthorizationException传至Subject的caller;而随后的Realm的验证方法都不会得到执行;如果Realm的权限验证方法返回boolean(比如hasRole或者isPermitted)并且其中一个返回true,剩余的Realm则全部短路