1. 前言
欢迎阅读 Spring Security 实战干货系列文章 。截止目前已经对 基于配置 和 基于注解 的角色访问控制进行了讲解。对于一些小项目来说基本是够用的。然而如果希望运营管理人员能够动态的配置和分配权限,以上两种方式显然是满足不了需求的。接下来我们来一起探讨一下思路。
2. 动态的权限控制同样依赖 RBAC 模型
我们依然应该在 RBAC 及其变种的基础上构建动态的权限控制系统。所有被访问的目标,无论是 API、静态资源都应该是关联了角色的东西统称为 资源(Resource)。我们需要建立起角色和资源之间的关系。
2.1 资源映射到角色
下面是一个资源到角色的映射关系图:
模型大致如上所示,每一个资源对应一个可能无重复的角色集(Set
集合);你可以注意到一个细节 Role 1
既指向 Resource 1
又指向 Resource 2
中,这是可以理解的,毕竟有可能对同一资源的访问权可能分散到多个角色中去;当然也可以互斥这取决于你的业务。
我们选择资源映射到角色是因为当请求时,资源是唯一的而角色可能是多个,如果进行反转的话解析的效率低一些。
3. 请求认证过程
这里有很多搞法,但是总体的思路是我们的请求肯定是带下面两个东西(起码在走到进行访问决策这一步是必须有的):
-
URI 访问资源必然要用 URI 来定位,我们同样通过 URI 来和资源接口进行匹配;最好是 Ant match,因为
/user/1
和/user/2
有可能访问的是同一个资源接口。如果你想避免这种情况,要么在开发规约中禁止这种风格,这样的好处是配置人员可以不必熟悉 Ant 风格;要么必须让配置人员掌握 Ant 风格。 -
Principal ,Spring Security 中为
Authentication
(认证主体),之前讲过的一个比较绕的概念,Spring Security 中的用户身份有两种 一种是 认证用户 另一种是 匿名用户 ,它们都包含角色。拿到角色到角色集进行匹配。
然后我画了一个下面的图来更加清晰的展示一下流程:
4. 如何结合安全框架
虽然本文是 Spring Security 系列的,但是我们如果使用其它安全框架或者自己研发安全框架都可以依据上面的思路。如果需要用编程语言总结一下就是我们需要两个接口来协同:
- 获取资源角色关系这些元数据的接口 这是我们动态权限控制的基石,只有将角色和资源的映射关系接口化才能动态的进行权限控制。 这里没有唯一标准,根据你的业务来设计。
- 对 Request 进行解析并和提取的元数据进行匹配的接口 这是我们动态权限控制的最终逻辑实现。 这里的规则同样也没有唯一标准
抓住了这两点之后我们就非常了然了,无非实现一个具有这两种功能的 Filter
,注入安全框架的过滤链中的合适位置中。要么你可以自己造个轮子,要么你使用现在有的轮子。那么有没有现成的轮子呢? 我一般建议如果你在造轮子前先看看你选型的安全框架有没有现成的轮子可用。当现成有轮子可用并且能够满足你的需要时往往能够事半功倍。如果没有合适的就造一个!
5. 总结
本篇主要理清一下动态权限所需要的一些要点,并对请求认证的过程进行了分析。最后对结合安全框架定制也提供了一些个人的见解。实现也写了大部分,之所以拆分成上下篇,因为理论和实现放在一篇的话实在有点篇幅过长,分成上篇理论、下篇实践更加合适。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。