论坛首页 综合技术论坛

深入讨论通用权限组件的理论和设计实现。

浏览 3031 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-02-03  
本人最近正在为公司的多个项目(包括未来项目)做通用的权限组件,个人有一些见解,也有不少困难,欢迎大家耐心阅读并指正。

目前已经发布了一个版本并供几个项目使用,先简单介绍一下组件的情况:

1.模式:建立在RBAC理论技术上的权限模式

2.技术:是以Java编写的一个组件(计划在下一个版本做成一个框架)

3.结构:包括两部分:
(A)权限配置管理平台,一个Web应用(即一个war包),用于注册受控资源,管理角色,和授权(把角色指派给宿主系统的用户),本平台是可选的
(B)权限服务组件,一个嵌入式组件(即一个jar包),提供访问控制服务和权限配置服务(后者供宿主系统通过接口调用实现权限配置管理,可以代替权限配置管理平台)

4.实现机制:权限相关数据与宿主系统的数据逻辑上式独立的,宿主系统通过嵌入权限组件,本地调用组件提供的相关服务接口实现权限配置管理和访问控制,组件提供四种服务:
(A)授权服务:用户访问宿主系统的受控资源时,宿主系统把用户ID和被访问资源ID传递到授权服务接口,授权服务接口返回是否可以访问的结果信息,宿主系统可以一次加载用户的所有权限信息,也可以在每次用户访问时才调用授权服务接口。
(B)实体管理服务:提供受控资源(实体)的增、删、改、查等管理服务。
(C)角色管理服务:提供角色的增、删改、查管理服务和为角色配置受控资源的服务
(D)授权管理服务:提供为宿主系统用户指派、移除角色的服务。
宿主系统可以把UI相关的实体名以URI来注册,权限组件提供默认的Filter进行拦截,对API的实体名以API对应的方法名的全限定名进行注册,权限组件提供默认的Interceptor以AOP的方式进行拦截,这样,宿主系统就不需要在业务层和页面层编写与权限控制相关的代码,权限这个功能编程了一个可以切入和移除的Aspect。

5.功能范围:目前只能控制功能权限,数据权限控制还没实现。



我的帖子将围绕以下几个方面讨论:

RBAC模型和相关概念
功能权限和数据权限
权限、角色与组织机构、用户之间的关系



1. RBAC模型和相关概念(以下观点是本人在理解RBAC模型之后结合个人意见的观点,如不合理,请指出并欢迎讨论)

1.1 术语定义:

受控资源:系统需要进行访问控制的资源,包括功能性资源和数据性资源,所以受控资源分为功能实体和业务实体:
(A)功能实体:从抽象角度来看,用户(不一定是人,也可以系统)使用系统只有两种途径:通过UI访问,如:按钮、页面、菜单等;通过API访问,如服务接口,DAO接口。经过这样的定义,对功能实体的操作就可以抽象成只有一种:访问。
(B)业务实体:即宿主业务系统相关的领域模型对象,如房地产交易系统的客户、楼盘、房间、合同等。对于业务实体,其操作可以抽象成四种:增加、删除、修改、读取。

操作行为:对受控资源的操作类型的抽象,对功能实体,操作行为只有“访问”,对业务实体,操作行为有“增加”、“删除”、“修改”、“读取”

权限:权限是实体+操作的组合,即“对‘什么资源’执行‘什么操作’”,因此,每个功能实体只能有一种权限,但每个业务实体,可以有最多四种权限。

角色:角色抽象上跟权限是同一概念,因为角色是反映用户可执行的权限,角色实际上是权限集,因为“人”会频繁变动,但“角色”却很少变动,所以才需要引入“角色”这个概念。

1.2 关系概念

实体之间的关系:实体与实体之间可以表现为从属关系和关联关系。
(A)从属关系,实体可以拥有一个父结点,多个子结点,拥有子结点权限的前提是必须拥有父结点权限,例如“楼盘信息”页面,拥有“查询楼盘”、“修改楼盘”两个按钮,那么“楼盘信息”页面这个功能实体就是“查询楼盘”和“修改楼盘”两个按钮功能实体的父结点,用户只有在拥有“楼盘信息”页面的访问权的前提下,才可能拥有“查询楼盘”和“修改楼盘”两个按钮的操作权。
(B)关联关系:实体之间的松散耦合关系,如A页面内嵌了C页面,B页面也内嵌了C页面,C既不属于A,也不属于B,这种情况,A与C、B与C之间就构成了关联关系。

角色与实体之间的关系:角色与实体之间存在多对多关系

角色之间的关系:扩展关系与排斥关系,建立这些关系主要是方便管理,对于正向授权,可以使用扩展关系,如角色A拥有1、2、3的权限,角色B比角色A多拥有4的权限,则角色B可以扩展角色A,然后为它指派4;对于反向授权,可以使用排斥关系,例子跟前者相反。对于这种关系还可以进一步扩展,就是一个角色可以扩展自多个角色,也可以排斥多个角色。根据实际情况,扩展关系比较常用。

1.3 存在争议

【讨论点1】其实对“业务实体”的操作最终都会表现为一种功能,如:对“合同”执行“修改”操作,可以被定位为“修改合同服务”这样一个功能,以业务接口的方式暴露出来,因为一般的业务系统设计中,业务系统并不会把纯数据的操作(即DAO)直接暴露给外界使用,而是把业务接口暴露给用户使用,用户只能通过业务接口对数据进行操作,不能直接操作一个业务对象。理论上,一个业务操作可能对应多于一个的业务实体的多于一个的操作,举个例子,删除一个可售楼盘信息这个业务,包括了多个业务实体操作:可售楼盘+删除、楼盘的房间+删除、销售信息+修改。所以,从更高一层的抽象看待“受控资源”,它可以全部被定义为功能实体,而对受控资源的“操作”,则都可以被抽象成“访问”。

【讨论点2】基于RBAC的理解模型,还应不应该允许直接把权限分配给用户,从本人的角度来看,由于权限对于大部分系统都是一个Aspect的问题,因此权限这个Aspect是不应该包括用户的,即权限模块的数据模型只有实体、角色及其之间的关系,用户作为另外一个Aspect(可以做成一个统一用户管理模块),如果只允许把角色与用户建立关系,不允许用户之间指派权限,则从系统角度来看,“权限控制”与“用户管理”作为业务系统的两个Aspect模块,他们之间的联系就会更加简单和清晰,就是“权限.角色”-“用户”。但另外一个问题是,很多时候,管理人员需要为某些特定的用户在他拥有的角色上根据实际需要分配多若干个权限,如果都需求定义角色,就会出现角色泛滥,不便管理了。这是从系统设计角度与现实情况角度相矛盾的地方。



2.功能权限和数据权限

2.1 概念定义
功能权限:在第1点已经阐述过,用户与业务系统进行交流,一般是面向服务的,即业务系统会把服务抽象成一个个功能点暴露给用户,功能权限实际上就是决定用户能否使用系统提供的功能点的问题,即“‘谁’对‘什么资源’进行‘什么操作’”(而根据上面的第1点的讨论点1,权限可以被简化为对功能实体的访问操作,即“‘谁’访问‘什么功能实体’”)。

数据权限:关于这个概念,有多种说法,有人认为对一个对象进行不同的操作就表现为数据权限,比如对“论坛帖子”进行“阅读”和“修改”、“删除”等属于数据权限,但本人认为(结合第1点的讨论点1),这归根结底还是功能权限(或者说,可以被定义为功能权限)。本人理解的数据权限,是指基于特定用户的权限控制,即“‘谁’访问‘什么资源’当中的‘哪些资源’”的问题,举个例子:分论坛A的版主与分论坛B的版主拥有同样的角色“版主”,即他们的功能权限是一致的,但A版主只能管理A论坛的帖子,B版主只能管理B论坛的帖子,这时,RBAC就不能解决这类权限问题,这种情况,角色就需要与组织结构有所联系了。进一步,更复杂的情况:高级经理能审批50万以上的合同,中级经理只能审批50万以下的合同,这就更加需要引入“规则”进行权限控制了。

2.2 权限组件是否(能否)把数据权限控制也纳入它的功能范围

本人对这点非常困惑,但经过各种权衡,本人设计的权限组件还是“暂时”不把数据权限纳入通用权限组件的范畴,理据如下:

(A)功能需求上的考虑:“权限”是一个很大的概念,也和模糊,功能性权限无可非议,是纯权限的功能,但对于如上述2.1所述两个例子,就存在角度问题,从权限功能角度看,它们属于权限的功能需求,但从业务的角度看,很明显,上述两个例子都属于业务规则,他们的权限会根据业务的变化而变化的,例如论坛的分版主原来只可以管理本版的数据,但需求改变了,他也可以管理其他版的数据;对于第二个例子,变化更加难于控制,可能需要上要求高级经理可以审批的金额数变化了,可能因为经理的级别变化了,甚至可能会加入更多的规则。这两个例子,后者更加偏向于业务规则,本人觉得这种于业务规则紧密集合的“权限”,不应归纳到“权限组件”去实现,但对于第一个例子,可以通过引入组织机构得到一定程度的解决,但这样也引出了一个新的问题:权限于组织机构的关系,对于业务系统来说,两者应该是两个独立的Aspect,还是应该整合在一起呢?这个问题在第3点进行讨论。

(B)系统设计上的考虑:系统设计的原则是功能独立单一,结构清晰,依赖耦合低,灵活和可扩展的。因此,我们目前主要的业务系统架构是:展示层-业务层-数据层,把所有业务逻辑集中在“业务层”统一管理,这样的好处有:
功能单一:各层负责各层的功能,只要是面向接口通讯,每一层的修改都是独立的,而且因为功能独立,也便于维护;
业务封装:所有业务被封装在业务层,使业务可以被灵活的组合和重用,业务与展示也分离了;
安全稳定:所有业务处理被封装到业务层中,无论外界传递一些什么破坏性数据过来,业务层都只做它该做的事,不会做它不该做的事情,例如用户用户系统的“修改用户基本信息”服务,但他尝试把密码也修改传递过来,而“修改用户基本信息”这一服务把所有业务逻辑封装了,它不会受外界影响,接收到用户信息对象时,即使密码被改变了,由于它的业务逻辑不处理密码,密码也不会被修改被持久化到数据库。
数据层独立:数据持久化动作交给数据层(通常是DAO)处理,DAO不管业务,把所有数据的访问都抽象为“增”、“删”、“改”、“查”,DAO可以被所有业务模块公用,也可以进行更换,例如因为性能或成本需要更换持久层ORM框架、更好数据库(更准确来说是数据源)。
而“权限”,这作为一个“横切面”的Aspect,根据AOP设计理论,是应该从系统的三层结构中分离开来的,三层架构是系统的一个“维度”,权限又是另外一个“维度”,彼此之间只有连接点(JoinPoint),没有耦合,彼此不可见。从这个角度来看,如果把与业务逻辑相关的所谓“权限”交给权限组件去做,则一来业务系统对权限组件依赖变成“硬性依赖”,二来业务逻辑被分散管理了。作为系统的设计人员,你会希望你的开发人员在修改业务逻辑的时候,需要从业务层和权限Aspect把零散的业务逻辑收集并理解吗?一旦将来系统的权限控制需求发生改变,需要更换权限组件,或者需要以硬件的方式来进行访问控制,你是不得不向上级领导申请人月资源去重新编写你的业务逻辑了吧?

(C)重技术实现角度考虑,如果需要把这类与业务规则有关系的数据权限控制交给权限组件实现,那么权限组件就需要设计成一个框架,提供标准的接口供业务系统根据不同的业务规则实现不同的访问控制策略,但需要抽象的定义一套能适应各种业务规则的接口(及其传递的参数,返回的结果),并不是一件十分容易的事情(当然,并不是不可能)。

(未完待续。。。)
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics