对权限管理建模

0、为什么要讨论这个?

权限管理是MES平台极为核心而重要的功能,但目前的实现,我们一直觉得是个短板。湘临说,每当提到权限这一块,都会冒出来重写它的冲动。我也心有戚戚焉。当前版本中已经实现的权限管理,有几个明显的不足。一是功能。当业务应用提出权限管理要求时,平台往往表示不支持,模型方面没有做这样的设计。二是服务不够。虽然有时模型能够支撑,但平台往往要添加新的接口,才能满足业务应用的要求。三者,看到这个模块内部的代码实现,觉得实在看不过眼。我重写它的冲动,要比湘临更强烈。

因此,借着MES平台版本升级的机会,我们和微软一起对权限管理的模型进行了较为深入的讨论:四五个人,讨论了两天,得到了一些初步的结论。

1、模型到底是什么?

讨论的过程中,老谭固执己见,坚持先讨论清楚权限管理的模型,再说其它。这把刘林憋得够呛,因为每提到一个概念,刘大师总是要想清楚其配置界面才算安心。大师刚开始还能画界面,后来再画,就被老谭非常武断地阻止了。

为什么这么做?因为配置界面是派生的东西,模型则是核心,尽可等讨论清楚模型后再考虑其配置界面,以及其它相关内容,如数据存储,提供的服务等等。模型作为核心,其表达能力决定了所能满足的需求,也就决定了最终能为业务应用提供什么服务。讨论清楚模型,也就有了一个稳定的基础。

那么,怎么才算把模型讨论清楚了,或者说,模型到底是什么?

模型有三个要素,只有把这三个要素都说清楚了,才算把模型说清楚了:结构、操作和约束。

结构:模型的结构描述了模型由那些部件组成,每个部件的内容是什么,这些部件之间的相互关系如何。例如,权限管理模型中包含用户、角色、权限这些部件,一个用户可以有多个角色,一个角色可以用于多个用户等等。这分明就是概念模型中的E-R图。结构决定了模型的表达能力。

操作:模型的操作是指可以施加在模型结构上的操作。有狭义和广义之分。狭义的操作是指修改性的,经过了这样的操作,会修改模型的内容。如增加角色(修改实体),为用户赋角色(修改关系)。广义的操作除了包含修改性的,也包含查询一类的。模型的操作体现了模型的表达能力,是定义服务的基础。

约束:模型的约束描述了模型的结构应满足的条件,对模型的状态进行解释。例如,如果一个角色包含的权限大,另一个角色包含的权限小,是否允许把这两个角色赋给同一个用户?如果允许,该用户的权限是什么?模型的约束保证了模型中数据的正确性。

经过这两天的讨论,我们其实才定下来权限模型的结构,对于模型的操作和约束,还没有顾得上。

2、应用场景举例

为了便于说明问题,先给出一个应用场景。这个场景来自能源管理应用:核算单元量值归并,即计算核算单元中各种能源介质的消耗量。

核算单元是分层的,炼油事业部是一个核算单元,它下面有炼油一厂、炼油二厂,炼油一厂下面有一车间、二车间,一车间下面有1#常减压装置,这些也都是核算单元。

能源按介质分多种,典型的如水、电、汽、风。

能源的消耗量有多个版本,如原始量,确认量,平衡量,平衡确认量。

对消耗量归并结果的操作也有多种,如查询、保存、提交、取消提交。

3、基本的RBAC模型

权限管理中,广为采用的模型是基于角色的访问控制(Role-based Access Control, RBAC)模型,其结构如下图所示。

我们也基于该模型定义MES平台的权限模型。在该模型的结构中,有几个组件是比较明确的:

  • 用户代表所有注册的用户;
  • 用户和角色之间是多对多的关系;
  • 角色是权限的集合。
  • 权限明确了可以对指定对象所施加的操作。

我们将权限记为P,将操作记为OP,对象记为OB。要确定一项权限,需同时确定操作和对象,也就是权限是操作和对象的二元组:
P = <OP,OB>

为了提高定义的效率,可以将权限定义为允许在对象集合上所施加的操作;同样,也可以定义为可以在指定对象上所施加的操作的集合。干脆,我们将两者都定义为集合:
P = <{OP},{OB}>

角色是权限的集合,我们用R代表角色,那么
R = {P} = {<{OP},{OB}>}

操作也相对清楚:应具有明确的业务含义。在上面的应用场景例子中,操作可以是保存、提交等,但其业务含义不够明确。我们建议定义为保存确认量、保存平衡量、提交确认量、提交平衡量等。但这不是强制性的,业务模块可以根据自己的需求定义所需的操作。从后面的讨论中可以看出,既可以将操作定义为保存,也可以定义为保存确认量,并达到相同的控制效果。

4、授权对象怎么定义?很麻烦!

在基于RBAC的权限模型中,用户、角色、权限,以及操作都定义都清楚了。授权对象怎么定义,费了我们很多时间去讨论。

假设要操作的对象都集成到了权限模块中,如介质,如核算单元。我们统一记为o

考虑下面几种情况。

情形一、针对单一对象授权

例如,某个用户只负责水这种能源介质。这种情况下,授权对象很简单,就是指定的能源介质。

这种情况下,OB = o

情形二、针对层次对象授权

例如,考虑车间这一级的核算单元,如果一个用户拥有对炼油一车间的操作权限,那么通常意味着拥有对该车间内所有装置的操作权限。也就是说,只需要将炼油一车间的操作权限授予某个用户,就不必再把该车间内装置的权限授予他了。这样可以有效减少授权的次数。

但问题没有这么简单。例如,拥有炼油一厂的操作权限,并不意味着拥有该分厂内所有车间的操作权限。这是因为分厂的统计员和车间统计员往往不是同一个人。

所以,麻烦就在于,在同一个层级结构中,有的授权意味着自动拥有下级的权限,有的则没有。

应该怎么定义授权对象,能同时满足上述两种情况?我们的思路是,在原始对象上加上一个属性,该属性明确权限是否延伸到下级。我们将这一属性记为e

这时,需要对授权对象进行扩展:
OB = [o,e],其中e就是附加到o上的属性,是一个布尔型的值。

情形三、针对多维授权

考虑权限管理精细化的情况:一个人只负责指定车间内指定介质的量值归并,如只负责炼油一厂一车间水的量值归并。这时上面的授权对象定义方法就不能满足这个要求了。因为分别对核算单元和介质授权,不能控制到上面的粒度,只能同时对核算单元和介质进行授权。

如果将核算单元和能源介质看成是不同的维度,同时对核算单元和介质进行授权就意味着对多维同时授权。这时,授权对象是由多个基础对象组成的多维对象,也就是基础对象的元组:
OB = <o1,o2, …>

再考虑到对每一维都有权限是否往下延伸的问题,就需要将情形二和三综合起来考虑,那么,授权对象可以定义为:
OB = <[o1,e1], [o2,e2], …>

如上图所示的三个授权对象:

  1. 负责一车间内水的操作,拥有对下级核算单元的操作权限。OB = <[一车间, Y], [水, Y]>。由于水这种对象没有下级,其属性是Y还是N无所谓。
  2. 负责炼油事业部电的操作,但不负责下级核算单元的操作。OB = <[炼油事业部, N], [电, Y]>。
  3. 负责炼油一厂内汽的操作,拥有对下级核算单元的操作权限。OB = <[炼油一厂, Y], [汽, Y]>。

5、逆向授权

能源管理中遇到过一种情形,一个核算单元下有很多节点,如100个,负责该核算单元的用户应该同时拥有这些节点的操作权限。但由于管理上的原因,其中一个节点由另外的部门负责。这时应该怎么授权?一种方法是,将99个节点的权限授予该用户。这样做,首先在操作上非常繁琐——为了阻止用户操作一个节点,而给他授权了99个对象。其次,在概念上不严谨,例如,如果该核算单元下面又加了一个节点,还要记得将该节点的权限授给这个用户。

我们决定在模型上解决这一问题。在角色上加一属性——该角色的权限可以是正向的,也可能是逆向的。当为逆向时,角色表示为:R = - {P}。

6、总结

综上,角色可以定义为:
R = ±{<[o1,e1], [o2,e2], …>}

接下来,要继续完善权限模型的结构,如角色的组合。

随后重点切换到限模型上的操作和约束。


已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页