点击上方蓝色“ 程序猿DD ”,选择“设为星标”
回复“ 资源 ”获取独家整理的学习资料!
作者 | 码农小胖哥
来源 | 公众号「码农小胖哥」
欢迎阅读 Spring Security 实战干货系列 文章 。 截止到上一篇我们已经能够简单做到用户主体认证到接口的访问控制了,但是依然满足不了实际生产的需要。 如果我们需要一个完整的权限管理系统就必须了解一下 RBAC ( Role-Based Access Control
基于角色的访问控制) 的权限控制模型。
在正式讨论 RBAC 模型之前,我们要思考一个问题,为什么我们要做角色权限系统?答案很明显,一个系统肯定具有不同访问权限的用户。比如付费用户和非付费用户的权限,如果你是 QQ音乐的会员那么你能听高音质的歌曲,如果不是就不能享受某些便利的、优质的服务。那么这是一成不变的吗? 有时候为了流量增长或者拉新的需要,我们又可能把一些原来充钱才能享受的服务下放给免费用户。如果你有了会员等级那就更加复杂了, VIP1 跟 VIP2 具有的功能肯定又有所差别了。主流的权限管理系统都是 RBAC 模型的变形和运用,只是根据不同的业务和设计方案,呈现不同的显示效果。下图展示了用户和角色以及资源的简单关系:
那为什么不直接给用户分配权限,还多此一举的增加角色这一环节呢? 当然直接给用户具体的资源访问控制权限也不是不可以。 只是这样做的话就少了一层关系,扩展性弱了许多。 如果你的系统足够简单就不要折腾 RBAC 了,怎么简单就怎么玩。 如果你的系统需要考虑扩展性和权限控制的多样性就必须考虑 RBAC 。 如果你有多个具有相同权限的用户,再分配权限的时候你就需要重复为用户去 Query (查询) 和 Add (赋予) 权限,如果你要修改,比如上面的 VIP1 增加一个很 Cool 的功能,你就要遍历 VIP1 用户进行修改。 有了角色后,我们只需要为该角色制定好权限后,将相同权限的用户都指定为同一个角色即可,便于权限管理。 对于批量的用户权限调整,只需调整该用户关联的角色权限,无需遍历,既大幅提升权限调整的效率,又降低了漏调权限的概率。 这样用户和资源权限解除了耦合性,这就是 RBAC 模型的优势所在。
RBAC 模型可以分为: RBAC0 、 RBAC1 、 RBAC2 、 RBAC3 四种。 其中 RBAC0 是基础,其它三种都是在 RBAC0 基础上的变种。 大部分情况下,使用 RBAC0 模型就可以满足常规的权限管理系统设计了。 不过一定不要拘泥于模型,要以业务需要为先导。 接下来简单对四种模型进行简单的介绍一下。
RBAC0 是基础,定义了能构成 RBAC 权限控制系统的最小的集合, RBAC0 由四部分构成:
用户(User) 权限的使用主体
角色(Role) 包含许可的集合
会话(Session)绑定用户和角色关系映射的中间通道。 而且用户必须通过会话才能给用户设置角色。
许可(Pemission) 对特定资源的特定的访问许可。
RBAC1 在 RBAC0 的基础之上引入了角色继承的概念,有了继承那么角色就有了上下级或者等级关系。 父角色拥有其子角色所有的许可。 通俗讲就是来说: 你能干的,你的领导一定能干,反过来就不一定能行。
在体育比赛中,你不可能既是运动员又是裁判员!
这是很有名的一句话。 反应了我们经常出现的一种职务(其实也就是角色)冲突。 有些角色产生的历史原因就是为了制约另一个角色,裁判员就是为了制约运动员从而让运动员按照规范去比赛。 如果一个人兼任这两个角色,比赛必然容易出现不公正的情况从而违背竞技公平性准则。 还有就是我们每个人在不同的场景都会充当不同的角色,在公司你就是特定岗位的员工,在家庭中你就是一名家庭成员。 随着场景的切换,我们的角色也在随之变化。 所以 RBAC2 在 RBAC0 的基础上引入了静态职责分离(Static Separation of Duty,简称SSD)和动态职责分离(Dynamic Separation of Duty,简称DSD)两个约束概念。 他们两个作用的生命周期是不同的;
SSD 作用于约束用户和角色绑定时。 1.互斥角色: 就像上面的例子你不能既是A又是B,互斥的角色只能二选一 ; 2. 数量约束: 用户的角色数量是有限的不能多于某个基数; 3. 条件约束: 只能达到某个条件才能拥有某个角色。 经常用于用户等级体系,只有你充钱成为VIP才能一刀999。
DSD 作用于会话和角色交互时。 当用户持有多个角色,在用户通过会话激活角色时加以条件约束,根据不同的条件执行不同的策略。
图就不画了就是在 RBAC0 加了上述两个约束。
我全都要!
RBAC1 和 RBAC2 各有神通。 当你拿着这两个方案给产品经理看时,他给了你一个坚定的眼神: 我全都要! 于是 RBAC3 就出现了。 也就是说 RBAC3 = RBAC1 + RBAC2 。
四个模型说完,我们来简单对其中的一些概念进行进一步的了解。
对用户的理解不应该被局限于单个用户,也可以是用户组(类似 linux
的 User Group), 或许还有其它的名字比如部门或者公司; 也可以是虚拟的账户,客户,甚至说第三方应用也可以算用户 。 所以对用户的理解要宽泛一些,只要是有访问资源需求的主体都可以纳入用户范畴。
角色是特定许可的集合以及载体。 一个角色可以包含多个用户,一个用户同样的也可以属于多个角色; 同样的一个角色可以包含多个用户组,一个用户组也可以具有多个角色,所以角色和用户是多对多的关系。 角色是可以细分的,也就是可以继承、可以分组的。
许可一般称它为权限。 通常我们将访问的目标统称为资源,不管是数据还是静态资源都是资源。 我们访问资源基本上又通过 api 接口来访问。 所以一般权限都体现在对接口的控制上。 再细分的话我将其划分为菜单控制,具体数据增删改查功能控制(前台体现为按钮)。 另外许可具有原子性,不可再分。 我们将许可授予角色时就是粒度最小的单元。
基于角色的访问控制(RBAC)已成为高级访问控制的主要方法之一。 通过RBAC,您可以控制最终用户在广义和精细级别上可以做什么。 您可以指定用户是管理员,专家用户还是最终用户,并使角色和访问权限与组织中员工的职位保持一致。 仅根据需要为员工完成工作的足够访问权限来分配权限。 通过上面的介绍相信一定会让你有所收获。 对我接下来的 Spring Security 实战干货 集成 RBAC 也是提前预一下热。 其实不管你使用什么安全框架, RBAC 都是必须掌握的。
如果你有什么问题可以留言讨论。 也可以通过关注公众号 Felordcn 与作者探讨:
本文通过OpenWrite的Markdown转换工具发布
关注我,回复“ 加群 ” 加入各种主题讨论群
Spring Security 实战:Spring Boot 下的自动配置
Spring Security 实战:路径Uri中的 Ant 风格
Spring Security 实战:自定义配置类入口
Spring Security 实战:搞清楚 UserDetails
Spring Security 实战:登录成功后返回 JWT Token
Spring Security 实战:实现自定义退出登录
Spring Security 实战:自定义异常处理
Spring Security 实战:使用 JWT 认证访问接口
朕已阅