漫谈权限系统之技术策略以及基于RBAC的实现
根据上面的需求描述以及对需求的分析,我们得知通常的一个中小型系统对于权限系统所需实现的功能以及非功能性的需求,在下面我们将根据需求从技术角度上分析实现的策略以及基于目前两种比较流行的权限设计思想来讨论关于权限系统的实现。
1.1. 技术策略
· 身份认证
在 B/S 的系统中,为识别用户身份,通常使用的技术策略为将用户的身份记录在 Session
中,也就是当用户登录时即获取用户的身份信息,并将其记录到 Session 里,当需要进行身份认证的时候通过从 Session
中获取用户的身份信息来实现用户的身份认证。
· 资源权限校验
资源权限校验取决于系统的授权模型,这块将在之后进行详细的阐述。
· 数据权限校验
数据权限校验取决于系统的授权模型,这块将在之后进行详细的阐述。
· 授权模型
授权模型作为权限系统的核心,从本质上决定了权限系统的易用性,这个易用性包括权限的授予和权限的校验,并同时也决定了权限的继承,权限的排斥和包含等方面的实现。
在经历了这么多年的发展,授权模型在目前中小型应用系统接受的比较多的主要有 RBAC 模型和 ACL 模型,将在之后展开专门的篇幅进行讲解。
· 权限校验的体现
权限校验的体现在中小型系统中体现出来的通常只是对于系统菜单、按钮显示的控制和对于拥有权限的数据的访问上。
它们共同依赖于资源权限校验和数据权限校验,对于系统菜单、按钮的显示上的控制在 B/S 中通常采用的技术策略为在生成菜单、按钮的 Html
时做权限级的判断,当操作主体不具备权限时则不生成该菜单、按钮的 Html
,从技术角度分析为方便使用者,避免使用者调用权限校验接口,通常的做法为提供菜单、按钮的标签,通过此标签生成的菜单和按钮即为经过权限过滤的。
· 高性能
为提高权限系统在授权以及校验权限时的性能,通常的做法为采用缓存技术以及加强权限系统的管理建设,加强权限系统的管理建设有助于建立一个最为适合需求的权限结构,同时做到了简化系统权限授予。
· 安全性
安全性方面来讲在 B/S 系统中通常有两个方面需要控制:
通过非法途径访问系统文件
在 Java 的 Web 应用中通常采用的技术策略为将需要受保护的文件放入 WEB-INF 文件夹中,大家都知道在 WEB-INF 下的文件除了在服务器上能直接访问外,通过普通的 URL 是无法访问到的。
其次的做法为做 Filter ,即对需要受保护的资源做访问的 Filter ,如操作者不具备权限则直接报出错误。
通过非法途径访问系统操作
通常采用的技术策略为对每个直接暴露对外的需要受权限保护的对象做操作级别的权限控制,简单来说在 Web 系统中通常采用 MVC 框架来实现,通常
Command 层是直接对外的,为防止用户通过 URL 或其他方式访问 Command
,从技术上我们需要考虑对现有系统的尽量少的侵入性,所以通常采用的做法是在 Command 之上做 Before Interceptor 或
Proxy ,在此 Interceptor 或 Proxy 中做权限的校验,以确认操作者具有相应的权限。
经过上面的描述,我们已经基本了解到满足权限系统需求的技术实现策略,从中我们也可以看出权限系统中最为重要的为授权模型,由于权限系统的通用性,在业界也是推出了不少的授权模型,在这里我们已目前比较通用的两种授权模型来具体讲解权限系统的完整实现。
1.2. 基于 RBAC 的实现
1.2.1. RBAC 介绍
RBAC 模型作为目前最为广泛接受的权限模型,在此也将对其模型进行简要的介绍, RBAC 模型成功的经典应用案例当属 Unix 系统了。
NIST
( The National Institute of Standards and Technology ,美国国家标准与技术研究院)标准
RBAC 模型由 4 个部件模型组成,这 4 个部件模型分别是基本模型 RBAC0 ( Core RBAC )、角色分级模型 RBAC1 (
Hierarchal RBAC )、角色限制模型 RBAC2 ( Constraint RBAC )和统一模型 RBAC3 (
Combines RBAC ) [1] 。 RBAC0 模型如图 1 所示。
图表 1 RBAC 0 模型
· RBAC0 定义了能构成一个 RBAC 控制系统的最小的元素集合
在 RBAC 之中 , 包含用户 users(USERS) 、角色 roles(ROLES) 、目标 objects(OBS) 、操作
operations(OPS) 、许可权 permissions(PRMS) 五个基本数据元素,权限被赋予角色 ,
而不是用户,当一个角色被指定给一个用户时,此用户就拥有了该角色所包含的权限。会话 sessions 是用户与激活的角色集合之间的映射。
RBAC0 与传统访问控制的差别在于增加一层间接性带来了灵活性, RBAC1 、 RBAC2 、 RBAC3 都是先后在 RBAC0 上的扩展。
· RBAC1 引入角色间的继承关系
角色间的继承关系可分为一般继承关系和受限继承关系。一般继承关系仅要求角色继承关系是一个绝对偏序关系,允许角色间的多继承。而受限继承关系则进一步要求角色继承关系是一个树结构。
· RBAC2 模型中添加了责任分离关系
RBAC2 的约束规定了权限被赋予角色时 , 或角色被赋予用户时 , 以及当用户在某一时刻激活一个角色时所应遵循的强制性规则。责任分离包括静态责任分离和动态责任分离。约束与用户 - 角色 - 权限关系一起决定了 RBAC2 模型中用户的访问许可。
· RBAC3 包含了 RBAC1 和 RBAC2
既提供了角色间的继承关系,又提供了责任分离关系。
1.2.2. 实现方案
通过上面章节对 RBAC 的介绍,从 RBAC 模型中我们可以看出它已经实现了一个使用起来很方便的授权模型,并同时也就权限的继承,权限的排斥和包含提出了解决的模型。
那么现在的关键是我们需要来看看基于 RBAC 到底是怎么实现权限系统的需求的呢?在这里我们针对在技术策略中未描述的授权模型和权限校验部分做实现方案的讲解。
· 授权模型
授权模型遵循 RBAC 进行搭建,即建立如上图表一的模型。
针对授权模型中的几个关键部分我们进行描述:
授权
按照 RBAC 的模型,在授权时分为配置资源以及资源的操作、授予角色对资源的操作权限、分配角色给用户这几个步骤来完成。
从这几个步骤我们进行分析:
配置资源以及资源的操作
实现这步非常的简单,直接维护资源以及资源操作两个对象的持久即可实现。
授予角色对资源的操作权限
实现这步同样非常的简单,维护角色与资源的关联模型即可。
分配角色给用户
实现这步同样非常的简单,维护角色与用户的关联模型即可。
权限的继承
权限的继承在 RBAC 的模型中通过增加角色的自关联来实现,即角色可拥有子角色,子角色继承父角色的权限。
按照此模型可以看出在授权时维护权限的继承也是非常的简单,维护角色的自关联模型即可。
权限的排斥和包含
权限的排斥和包含这块我没有具体看 RBAC 的规范,通常的做法是通过在资源的操作权限模型中增加自关联模型以定义哪些资源的操作权限是排斥和包含的,在授权时可以看到同样需要维护的只是资源权限的自关联模型。
· 资源权限校验
根据上面的授权模型,在做资源权限校验的时候需要经过以下步骤:
判断用户所在的角色是否拥有对资源进行操作的权限
获取用户所拥有的角色,遍历其角色,以各角色建立 Session ,并通过类似的 role.doPrivilege(Resource,Operation) 的方式来判断该角色是否具备权限,如具备则直接返回,如不具备则直到遍历结束。
递规用户所在角色的父角色判断是否拥有对资源进行操作的权限
当遍历完用户本身的角色得到用户不具备对资源进行该操作的权限时,则开始递规其所在角色的父角色来判断是否拥有对资源进行操作的权限,过程同上,如确定某角色具备,则返回,如不具备直到递规结束。
· 数据权限校验
在 RBAC 模型中没有明确定义数据权限的实现策略,鉴于此首先要讲解下基于 RBAC 模型的数据授权模型的建立,基于 RBAC
模型,将数据映射为 RBAC
中的资源,对数据的操作则映射为资源的操作,同样的是将此资源以及资源的操作构成的权限授予给角色,将用户分配给角色完成数据权限的授权过程。
但根据数据权限校验的需求,数据的权限也是需要继承的,而且数据权限的授予对象需要是多种,这样的话就对上面根据 RBAC 映射形成的数据权限的授权模型造成了冲击,需要重构上面的授权模型来满足需求。
为实现数据权限的继承,需要将 RBAC
模型中的资源重构为允许自关联的模型,为实现数据权限能够授予给多种对象,需要将本来资源操作权限授予给角色的模型演变为数据操作权限授予给角色、组织机
构或具体人员,根据 RBAC 模型,同样的建立一个中间对象,此对象和数据操作权限所授予的对象做 1
对多的关联,在经过这样的重构之后数据权限的授权模型就形成了,也满足了数据权限的继承和授予给多种对象的需求。
图表 2 基于 RBAC 演变的数据权限模型
上面的图中少画了数据的自关联。根据上面的数据权限模型,来看看数据权限的校验是怎么样去实现呢?
在做数据权限校验的时候我们需要实现的为两种方式,一种是获取操作主体具有数据操作权限的全部数据,另外一种为分页获取操作主体具有数据操作权限的数据。
就这两种方式分别来进行阐述:
获取操作主体具有数据操作权限的全部数据
从数据库中获取所有数据,遍历取出的数据从数据权限模型中获取相应的拥有数据操作权限的权限拥有者,如果该数据未配置数据操作权限的控制,那么就无需对该
数据进行权限级的判断,如配置了,则需判断当前用户是否在该数据操作权限所对应的拥有者中,如用户不在,则需递规获取该数据的父数据的操作权限的拥有者,
到用户拥有权限或递规结束时终止。
分页获取操作主体具有数据操作权限的数据
分页的做法和上面差不多,只是在获取了所有的数据后在内存中做分页返回。
1.2.3. 优缺点分析
从上面的基于 RBAC 的实现方案中可以看出基于 RBAC 模型的优点在于:
· 易用和高效的授权方式
用户在进行授权时只需对角色进行授权,之后将相应的角色分配给用户即可。
· 简便和高效的授权模型维护
在技术角度来讲,进行授权模型的维护上因为基本只需要维护关联模型而显得简单而高效。
缺点在于:
· 复杂的权限校验
在进行权限校验时需要不断的遍历和递规,造成了性能的影响。
· 对于数据权限的不够支持
没有明确的数据权限模型,可以看到在经过重构的数据权限模型其实已经和 RBAC 模型有一定的出入,而且在数据权限的校验上实现起来是非常的低效。