权限管理--网上论坛节选

来源:互联网 发布:怎么看mac系统版本 编辑:程序博客网 时间:2024/06/05 10:02

前言:

权限是一个极其复杂的问题,但可以简单表述为:判断“who 对 what(which) 进行 how 的操作”的逻辑表达式是否为真。

针对不同的应用,需要根据项目的实际情况和具体架构,在维护性、灵活性、完整性等N多个方案之间比较权衡,选择符合的方案。


理解:

这个权限系统的设计,我主要考虑了这么几个方面:

直观,因为系统最终会由最终用户来维护,权限分配的直观和容易理解,显得比较重要,系统不辞劳苦的实现了组的继承,就是以为它足够直观。

简单,包括概念数量上的简单和意义上的简单,以及功能上的简单。想用一个权限系统解决所有的权限问题是不现实的。设计中将“定制”特点比较强的部分判断为业务逻辑,而将“通用”特点比较强的部分判断为权限逻辑就是基于这样的思路。

扩展,我在以前的项目中也实现过基于 Role 概念的权限系统,效果不太理想。这里之所以不采用 Role 的概念,就是因为它不易扩展。通常 Role 的设计方式意味着预先已经定好的一组权限,而,因为这样的“预先设计”,常常会鼓励程序员 hardcode 这些权限相关的部分。当需要重新定义 Role 时,扩展就会变得极为困难。而采用可继承的 Group 概念也可以支持权限的重新定义,但有效的避免了扩展方面的缺点。


名词:

下面两个名词极其重要,是整个设计问题边界定义的关键,或许我的理解与通常的理解不同,在此有必要特别澄清。

粗粒度:表示类别级,即,仅考虑对象的类别,不考虑对象的某个特定实例。比方,用户管理中,创建、删除,对所有的用户都一视同仁,并不区分操作的具体对象实例。

细粒度:表示实例级,即,需要考虑具体对象的实例,当然,细粒度是在考虑粗粒度的对象类别之后才再考虑特定实例。比方,合同管理中,列表、删除,需要区分该合同实例是否为当前用户所创建。


原则:

权限逻辑配合业务逻辑。即,权限系统以为业务逻辑提供服务为目标。纯粹纸面意义的权限系统,这里不予讨论。而且,相当多细粒度的权限问题极其独特不具通用意义,它们也可以被理解为是“业务逻辑”的一部分。比方,要求:“合同资源只能被它的创建者删除,与创建者同组的用户可以修改,所有的用户能够浏览”。这既可以认为是一个细粒度上的权限问题,也可以认为是一个细粒度上的业务逻辑问题。在这里我认为它是业务逻辑问题,在整个权限系统的架构设计之中不予过多考虑。当然,权限系统也必须要能够支持这样的控制判断。或者说,系统提供足够多但不是完全的控制能力。即,设计原则可以归结表述为:“系统只提供粗粒度的权限,细粒度的权限被认为是业务逻辑的职责”。

需要再次强调的是,这里表述的权限系统仅仅是一个“不完全”的权限系统,即,它不提供所有关于权限的问题的解决方法。它提供一个基础,并解决那些具有“共性”的(或者说粗粒度的)部分。在这个基础之上,根据“业务逻辑”的独特权限需求,编码实现细粒度的部分,才算完整。回到权限的问题公式,我的设计仅仅解决了 who + what + how 的问题,which 的权限问题被当作是业务逻辑。


概念:

User:用户。解决 who 的问题。
Group:组。权限分配的单位与载体。权限不考虑分配给特定的用户。组可以包括组(以实现权限的继承)。
Operate:操作。表明对 what 的 how 操作。


说明:

User

与大家的都一样,没什么好说的。

Group

与大家的类似,所不同的是,Group 要实现继承。即,在创建时必须要指定该 Group 的 Parent 是什么 Group 。在粗粒度控制上,可以认为,只要某用户直接或者间接的属于某个 Group 那么它就具备这个 Group 的所有操作许可。细粒度控制上,在业务逻辑的判断中,User 仅应关注其直接属于的 Group ,用来判断是否“同组”,间接的 Group 对权限的控制意义不大。试设想存在一个 All User 的 Group 是所有 Group 的祖先,这样的情形下,判断的结果不具备实际意义。

User 与 Group 是多对多的关系。即,一个 User 可以属于多个 Group 之中,一个 Group 可以包括多个 User 。

子 Group 与 父 Group 是多对一的关系。即,一个子 Group 只能有一个父 Group ,一个父 Group 可以包括多个子 Group 。


Operate

某种意义上类似于大家的 Resource + Privilege 概念,但,这里的 Resource 仅包括 Resource Type 不表示 Resource Instance。

Group 与 Operate 是多对多的关系。

各概念的关系图示如下:

 User  |*  |  |*   1 Group---+  |* |*  |  |  +---+  |* Operate



解释:

之所以将 Resource Type 和 Operate 绑定在一个概念里而不是分开建模再建立关联,是因为很多的 Operate 对于某 Type 的 Resource 才有意义。比方,发布操作对新闻对象才有意义,对用户对象则没有意义。

操作本身的意义也大大拓展,这里并非仅定义类 UNIX 的 RWX 三种操作(这样的定义对于文件系统是合理的,对于其他的应用领域或许就不是那么足够了),而是定义了 N 种具体的操作。比方,对于合同的创建操作、提交操作、检查冲突操作等。可以认为,操作概念对应于每一个商业方法。

其中,与具体用户身份相关的操作既可以定义在操作的业务逻辑之中,也可以定义在操作级别。比方,创建者的浏览视图与普通用户的浏览视图要求内容不同。你既可以在外部定义两个操作方法,也可以在一个操作方法的内部根据具体逻辑进行处理。具体应用哪一种方式应依据实际情况处理。

这样的架构,应能满足绝大部分粗粒度权限控制的功能需要。但是,除了粗粒度权限,无可否认,系统中必然还会包括无数对具体 Instance 的细粒度权限。这些问题,在这里被认为是业务逻辑的职责。

一方面,细粒度的权限判断必须要在资源上建模权限分配的支持信息才可能得以实现。比方,如果要求创建者和普通用户看到不同的信息内容,那么,资源本身应该有其创建者的信息。如同 Unix 的每一个文件(资源),都定义了对 Owner, Group, All 的不同操作信息。

另一方面,细粒度的权限判断具有相当大的业务逻辑相关性。对不同的业务逻辑,常常意味着截然不同的权限原则和方式。相比之下,粗粒度的权限更具通用性,将其实现为一个架构,更有重用价值;而将细粒度的判断方式与逻辑实现为一个架构级别的东西就显得不是那么的有必要了,而用代码级别来实现就显得更为灵活一些。

原创粉丝点击