授权
授权,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的。
授权的关键对象
授权可简单理解为Who对What / Which进行How操作。
- Who:主体(Subject),主体需要访问系统中的资源。
- What / Which:资源(Resource),如系统菜单、页面、按钮、类方法、系统商品信息等。资源包括资源类型和资源实例,比如商品信息为资源类型,类型为Type01的商品为资源实例,编号为001的商品信息也属于资源实例。
- How:权限(Permission),规定了主体对资源的操作许可。权限离开资源没有意义,如用户查询权限、用户添加权限、某个类方法的调用权限、编号为001用户的修改权限等,通过权限可知主体对哪些资源都有哪些操作许可。
授权流程
授权一定是基于认证通过后才执行的操作。
授权方式(RBAC)
RBAC主要包含两种授权模式:
- 基于角色的访问控制(Role-Based Access Control):以角色为中心进行访问控制。
伪代码可表示为:
1 | java复制代码if (subject.hasRole("admin")) { |
- 基于资源的访问控制(Resource-Based Access Control):以资源为中心进行访问控制。
伪代码可表示为:
1 | java复制代码if (subject.isPermitted("user:find:*")) { |
isPermission
传入参数是一个权限字符串,其格式为 “资源类型 : 操作 : 资源实例” 。“ user : find : * “ 表示的是Subject对所有User实例具有查询的权限(操作类型)。
“ user : * : 001 “ 表示的是Subject对ID为001的User实例具有所有的权限(操作实例)。
Shiro权限字符串
1. 组成规则
在Shiro中使用权限字符串必须按照Shiro指定的规则。
权限字符串组合规则为:“资源类型标识符 : 操作 : 资源实例标识符”
- 资源类型标识符: 一般会按模块,对系统划分资源。比如user模块,product模块,order模块等,对应的资源类型标识符就是:user,product,order。
- 操作: 一般为增删改查(create,delete,update,find),还有 * 标识统配。
- 资源实例标识符: 如果Subject控制的是资源类型,那么资源实例标识符就是 “*“ ;如果Subject控制的是资源实例,那么就需要在资源实例标识符就是该资源的唯一标识(ID等)。
2. 示例
“ * : * : * “ 表示Subject对所有类型的所有实例有所有操作权限,相当于超级管理员。
“ user : create : * “ 表示Subject对user类型的所有实例有创建的权限,可以简写为:” user : create “。
“ user : update : 001 “ 表示Subject对ID为001的user实例有修改的权限。
“ user : * : 001 “ 表示Subject对ID为001的user实例有所有权限。
Shiro授权方式
Shiro中对于后台授权提供了三种实现方式:
- 编程式
- 注解式
- 标签式(已淘汰,只能在JSP,Thymeleaf等模板引擎中使用)
1. 编程式
1 | java复制代码Subject subject = SecurityUtils.getSubject(); |
2. 注解式
1 | java复制代码@RequiresRoles("admin") |
Shiro授权源码
SimpleAccountRealm
类就是Shiro默认完成认证和授权的底层操作,其中 doGetAuthenticationInfo
方法处理认证 ,doGetAuthorizationInfo
方法处理授权。
1 | java复制代码public class SimpleAccountRealm extends AuthorizingRealm { |
Shiro授权Demo
授权必须在认证的基础上,因此本Demo基于前文中MD5加密认证的Demo实现授权。
1. 基于角色访问控制
在定义Realm中的授权操作中给Subject添加角色
1 | java复制代码public class UserMD5Realm extends AuthorizingRealm { |
授权流程
1 | java复制代码public static void main(String[] args) { |
2. 基于权限访问控制
在定义Realm中的授权操作中给Subject添加授权信息
1 | java复制代码public class UserMD5Realm extends AuthorizingRealm { |
授权流程
1 | java复制代码public static void main(String[] args) { |
本文转载自: 掘金