通用权限管理设计篇(一)

cqm

贡献于2011-05-20

字数:8315 关键词:

通用权限管理设计篇(一) 2009年01月13日    社区交流 关键字: 通用权限 Human Task Software Architect WebSphere MQ Rational Functional Tester 权限系统一直以来是我们应用系统不可缺少的一个部分,若每个应用系统都重新对系统的权限进行设计,以满足不同系统用户的需求,将会浪费我们不少宝贵时间,所以花时间来设计一个相对通用的权限系统是很有意义的。 [AD]   一.引言    因为做过的一些系统的权限管理的功能虽然在逐步完善,但总有些不尽人意的地方,总想抽个时间来更好的思考一下权限系统的设计。    权限系统一直以来是我们应用系统不可缺少的一个部分,若每个应用系统都重新对系统的权限进行设计,以满足不同系统用户的需求,将会浪费我们不少宝贵时间,所以花时间来设计一个相对通用的权限系统是很有意义的。   二.设计目标    设计一个灵活、通用、方便的权限管理系统。    在这个系统中,我们需要对系统的所有资源进行权限控制,那么系统中的资源包括哪些呢?我们可以把这些资源简单概括为静态资源(功能操作、数据列)和动态资源(数据),也分别称为对象资源和数据资源,后者是我们在系统设计与实现中的叫法。   系统的目标就是对应用系统的所有对象资源和数据资源进行权限控制,比如应用系统的功能菜单、各个界面的按钮、数据显示的列以及各种行级数据进行权限的操控。   三.相关对象及其关系    大概理清了一下权限系统的相关概念,如下所示:   1.    权限   系统的所有权限信息。权限具有上下级关系,是一个树状的结构。下面来看一个例子   系统管理   用户管理    查看用户   新增用户    修改用户    删除用户    对于上面的每个权限,又存在两种情况,一个是只是可访问,另一种是可授权,例如对于“查看用户”这个权限,如果用户只被授予“可访问”,那么他就不能将他所具有的这个权限分配给其他人。   2.    用户   应用系统的具体操作者,用户可以自己拥有权限信息,可以归属于0~n个角色,可属于0~n个组。他的权限集是自身具有的权限、所属的各角色具有的权限、所属的各组具有的权限的合集。它与权限、角色、组之间的关系都是n对n的关系。   3.    角色   为了对许多拥有相似权限的用户进行分类管理,定义了角色的概念,例如系统管理员、管理员、用户、访客等角色。角色具有上下级关系,可以形成树状视图,父级角色的权限是自身及它的所有子角色的权限的综合。父级角色的用户、父级角色的组同理可推。   4.    组   为了更好地管理用户,对用户进行分组归类,简称为用户分组。组也具有上下级关系,可以形成树状视图。在实际情况中,我们知道,组也可以具有自己的角色信息、权限信息。这让我想到我们的QQ用户群,一个群可以有多个用户,一个用户也可以加入多个群。每个群具有自己的权限信息。例如查看群共享。QQ群也可以具有自己的角色信息,例如普通群、高级群等。   针对上面提出的四种类型的对象,让我们通过图来看看他们之间的关系。      有上图中可以看出,这四者的关系很复杂,而实际的情况比这个图还要复杂,权限、角色、组都具有上下级关系,权限管理是应用系统中比较棘手的问题,要设计一个通用的权限管理系统,工作量也着实不小。   当然对于有些项目,权限问题并不是那么复杂。有的只需要牵涉到权限和用户两种类型的对象,只需要给用户分配权限即可。   在另一些情况中,引入了角色对象,例如基于角色的权限系统, 只需要给角色分配权限,用户都隶属于角色,不需要单独为用户分配角色信息。   在下一篇中,我们将讲述权限管理的数据库设计等内容。   欢迎各位拍砖或给出宝贵意见。 通用权限管理设计篇(二)——数据库设计 2009年01月13日    社区交流 [AD] 关键字: 通用权限 Human Task Software Architect WebSphere MQ Rational Functional Tester 下面让我们在PowerDesigner中画出各表吧。 [AD]   理清了对象关系之后,让我们接着来进行数据库的设计。在数据库建模时,对于N对N的 关系,一般需要加入一个关联表来表示关联的两者的关系。初步估计一下,本系统至少需要十张表,分别为:权限表、用户表、角色表、组表、用户权限关联表、用 户角色关联表、角色权限关联表、组权限关联表、组角色关联表、用户属组关联表。当然还可能引出一些相关的表。下面让我们在PowerDesigner中画出各表吧。    各表及其关系如下:       1.    用户表   用户表(TUser)   字段名称   字段   类型   备注   记录标识   tu_id   bigint   pk, not null   所属组织   to_id   bigint   fk, not null   登录帐号   login_name   varchar(64)   not null   用户密码   password   varchar(64)   not null   用户姓名   vsername   varchar(64)   not null   手机号   mobile   varchar(20)   电子邮箱   email   varchar(64)   创建时间   gen_time   datetime   not null   登录时间   login_time   datetime   上次登录时间   last_login_time   datetime   登录次数   count   bigint   not null   2.    角色表   角色表(TRole)   字段名称   字段   类型   备注   角色ID   tr_id   bigint   pk, not null   父级角色ID   parent_tr_id   bigint   not null   角色名称   role_name   varchar(64)   not null   创建时间   gen_time   datetime   not null   角色描述   description   varchar(200)   3.    权限表   权限表(TRight)   字段名称   字段   类型   备注   权限ID   tr_id   bigint   pk, not null   父权限   parent_tr_id   bigint   not null   权限名称   right_name   varchar(64)   not null   权限描述   description   varchar(200)   4.    组表   组表(TGroup)   字段名称   字段   类型   备注   组ID   tg_id   bigint   pk, not null   组名称   group_name   varchar(64)   not null   父组   parent_tg_id   bigint   not null   创建时间   gen_time   datetime   not null   组描述   description   varchar(200)   5.    角色权限表   角色权限表(TRoleRightRelation)   字段名称   字段   类型   备注   记录标识   trr_id   bigint   pk, not null   角色   Role_id   bigint   fk, not null   权限   right_id   bigint   fk, not null   权限类型   right_type   int   not null(0:可访问,1:可授权)   6.    组权限表   组权限表(TGroupRightRelation)   字段名称   字段   类型   备注   记录标识   tgr_id   bigint   pk, not null   组   tg_id   bigint   fk, not null   权限   tr_id   bigint   fk, not null   权限类型   right_type   int   not null(0:可访问,1:可授权)   7.    组角色表   组角色表(TGroupRoleRelation)   字段名称   字段   类型   备注   记录标识   tgr_id   bigint   pk, not null   组   tg_id   bigint   fk, not null   角色   tr_id   bigint   pk, not null   8.    用户权限表   用户权限表(TUserRightRelation)   字段名称   字段   类型   备注   记录标识   tur_id   bigint   pk, not null   用户   tu_id   bigint   fk, not null   权限   tr_id   bigint   fk, not null   权限类型   right_type   int   not null(0:可访问,1:可授权)   9.    用户角色表   用户角色表(TUserRoleRelation)   字段名称   字段   类型   备注   记录标识   tur_id   bigint   pk, not null   用户   tu_id   bigint   fk, not null   角色   tr_id   bigint   fk, not null   10.  用户组表   用户组表(TUserGroupRelation)   字段名称   字段   类型   备注   记录标识   tug_id   bigint   pk, not null   用户   tu_id   bigint   fk, not null   组   tg_id   bigint   fk, not null   11.  组织表   组织表(TOrganization)   字段名称   字段   类型   备注   组织id   to_id   bigint   pk, not null   父组   parent_to_id   bigint   not null   组织名称   org_name   varchar(64)   not null   创建时间   gen_time   datetime   not null   组织描述   description   varchar(200)   12.  操作日志表   操作日志表(TLog)   字段名称   字段   类型   备注   日志ID   log_id   bigint   pk, not null   操作类型   op_type   int   not null   操作内容   content   varchar(200)   not null   操作人   tu_id   bigint   fk, not null   操作时间   gen_time   datetime   not null 作者:天外流星    责编:豆豆技术应用 通用权限管理系统设计篇(三)——概要设计说明书 http://tech.ddvip.com   2009年01月13日    社区交流 [AD] 关键字: 通用权限 Human Task Software Architect WebSphere MQ Rational Functional Tester 今天抽时间整了一份概念设计出来,还有一些地方尚未考虑清楚,贴出1.0版,希望各位朋友提出宝贵建议。 [AD]   本文示例源代码或素材下载   在前两篇文章中,不少朋友对我的设计提出了异议,认为过于复杂,当然在实际的各种系统的权限管理模块中,并不像这里设计得那么复杂,我以前所做的系统中, 由只有用户和权限的,有只有用户、权限和角色的,还有一个系统用到了用户、权限、角色、组概念,这个系统是我在思考以前所做系统的权限管理部分中找到的一 些共性而想到的一个设计方案,当然还会有不少设计不到位的地方,在设计开发过程中会慢慢改进,这个系统权当学习只用,各位朋友的好的建议我都会考虑到设计 中,感谢各位朋友的支持。   今天抽时间整了一份概念设计出来,还有一些地方尚未考虑清楚,贴出1.0版,希望各位朋友提出宝贵建议。   附件为《通用权限管理概要设计说明书》,这是1.0版本,有些地方可能还会进行部分修改,有兴趣的朋友请关注我的blog。 通用权限的设计(上) http://tech.ddvip.com   2009年01月09日    社区交流 收藏本文 [AD] 关键字: ASP.NET MVC DDoS NAC NoScript 反渗透 本文详细介绍通用权限的设计(上) [AD]   讲权限模块的设计,其实没什么太大的意义,园子里面很多高人已经写过了。前段时间自己写了一个权限模块,现在跟大家分享一下做法。   讲我的做法之前,先要说说比较通用的权限模块是如何设计的,通常是一张用户表,角色表,用户与角色关联表,功能表,角色与功能关联表,模块表。   如上设计之后,当要判断一个用户是否具有某个权限的时候先要从用户与角色关联表出发,找到当前用户所属的角色,然后再去角色功能关联表里面查找用户所属角色所具有的功能点。查找出来的用户具有功能点是一个集合,还要把当前的功能点与集合里面的所有功能点比较,如果在集合里面找到了功能点,就证明此用户具备该功能点的权限,否则就证明该用户不具备此功能点的权限。   以上做法看似繁琐,但是大部分的操作都是在用户登陆的时候就把其对应的功能点集合取出,放入Session中,那么以后判断用户是否具备某个功能点的时候只需要把功能点与Session当中的功能点集合遍历比较即可。虽然极大的避免了查库,但是还有没有一种更好的做法能取代这种功能点遍历查找,让权限的判断与集合完全无关呢?   我们先举个例子,这里用二进制的方式来表示:   假如有如下功能点以及对应的二进制码   增加——0001   删除——0010   修改——0100   查找——1000   如上定义之后,我们假设一个用户A具有增加以及删除的权限,那么我们把增加以及删除操作的二进制码进行按位或操作:0001 | 0010 = 0011   我们把0011赋给用户A,那么当我们要判断此用户是否具备增加操作的时候,只需要把增加操作的二进制码与赋给用户A的二进制码进行按位与操作:0001 & 0011 = 0001   你是否已经看出点端倪了,只要计算的结果等于要判断的功能点的二进制码,就证明用户A具有该功能点的权限了。这样的话,判断某个用户是否具备某个功能点的权限的时候只需要把用户的二进制码与功能点的二进制码进行按位与操作即可。每次判断都非常简单。   下面放出我的设计:      从上图可以看到模块表与功能表有关联,但是功能点与角色表不再有关联,因为当创建角色之后,权值(之前所说的二进制码)就已经计算好并且加入到角色表当中,从此与后面的模块表与功能表脱节无关。用户与角色有关联,是为了用户与角色可以是多对多的关系,一个用户可以具备多个角色的权限,一个角色可以对应多个用户。   这次就先说到这里,下篇再详细说说创建角色,更新角色,创建用户等更多具体操作如何实现。   相关文章: 通用权限的设计(下) http://tech.ddvip.com   2009年01月09日    社区交流 收藏本文 [AD] 关键字: ASP.NET MVC DDoS NAC NoScript 反渗透 本文详细介绍通用权限的设计(下) [AD]   我在通用权限的设计(上)一文中很多问题并没有诉说详细,而且估计我写“通用”两字的时候激发了很多人的不满,我这里先道个歉。   从解决方案的角度出发,没有绝对通用的权限设计,这点我也赞同,只能针对项目的实际需求来开发对应的权限模块,这点是肯定的。我这里只是记录一种做法而已,而且这种做法必然有其适用的范围,而且如果把企业或者公司部门的因素也考虑进去,我觉得反而难以把做法说清,所以选择用最简单的设计来说明问题。实际情况下肯定要针对简单设计来做扩展的。   上篇的图这里再插入一遍:      我简单的说明一下,Application为功能模块表,他实际上没有什么具体作用,只是用来约束功能点的归属而已。Permission才是核心的功能点表,字段有最简单的功能名以及其他的字段,其中最重要的是功能点对应的权值(上篇说到的二进制编码),实际上这里没必要用0010这样的方式来保存,如果你的系统很小,功能点很少,那么可以用int类型来保存,权值只要满足2的n-1次方即可,至于原因是什么,我这里就没必要做说明了。那么以后业务扩充的功能点,只要满足这个权值规律就行了。如果系统的功能点再多点,可以考虑用bigint来保存,如果再大,可以考虑更大的类型来保存,甚至用字符来保存都可以,至于代码的接收,同样的需要有对应的类型来保存,小的不用说,大的可以参考http://pavelsem.blogspot.com/2008/04/big-number-calculations-in-c.html。针对这个功能表,我们可以做一个针对功能点的增删改操作,每次按照权值规律来赋值新的功能点,当然如果你比较懒,每次都在数据库里面加也可以,但是当数值较大的时候,每次估计都得拿个计算机来按了。所以大家大可估算一下这种做法的适用范围,以及当权值很大的时候,这种做法与传统做法哪中更好。   讲完功能点,应该来讲一下如何创建角色,为什么角色与功能点之间完全没有关联,实际上很简单,我在上篇中已经把这个道理说明了,如果我们的功能点仍然有增加,删除,修改,查看,对应的权值分别是1,2,4,8,那么当我们创建一个角色B,要求角色B拥有这四个功能点的时候只需要进行如下操作:1 + 2 + 4 + 8 =15 即可,把15这个值以及新建的角色信息存入角色表即可。那么当用户登陆的时候,只需要从用户角色对应表当中找到对应的角色,并把角色的权值做计算即可,假如又有角色C的权值为1,而用户A同时具备角色B以及角色C,那么当用户登陆的时候只要根据关联表找到他对应的两个角色,再把角色B以及角色C的权值进行按位或操作,即:1 | 15 = 15,15这个值就是用户A所具有的权值了,我们把这个权值保存起来,放入Session或者Cookies当中,显然15这个权值与1,2,4,8做按位与操作的时候皆可得到1,2,4,8,于是用户A就得到了角色B以及角色C的权限,并且角色B跟角色C的权限已经进行了合并。至此,用户登陆完之后就与数据库脱离了关系,所有权限的判断只需要拿具体功能点的权值与用户的权值进行按位与操作即可,不用再查表或者遍历功能点集合。至于角色的更新,只需要把新计算出来的权值更新到对应的角色即可。   针对实际情况,我们不可能在判断某个用户是否有某个功能点的时候都拿个数来与当前用户的权值做比较,更多是把它抽象为一个方法: if (roleHandle.CheckUserPer("CreateTipType")) {   //.. }   如上所示,CreateTipType对应的是一个业务的功能点名称,他对应一个权值,以上所说的过程全部集成在一个方法里面判断就可以了,当然你要用什么方式来做你的功能点与权值的对应都可以,并不一定要用名称,也可以用约定好的数字甚至其他表达方式都可以,但是绝对比你直接传个数字来得直观。   采用这种做法的时候,还会碰到很多具体的问题,诸如菜单的生成,权值的配置,角色的配置,角色的更新,用户权值的更新与保存等实际问题,我这里就不做一一说明了,感兴趣的朋友我们可以一起讨论。   相关文章: 应用程序权限设计 我们在开发系统的时候,经常会遇到系统需要权限控制,而权限的控制程度不同有不同的设计方案。   1.       基于角色的权限设计 这种方案是最常见也是比较简单的方案,不过通常有这种设计已经够了,所以微软就设计出这种方案的通用做法,这种方案对于每一个操作不做控制,只是在程序中根据角色对是否具有操作的权限进行控制;这里我们就不做详述 2.       基于操作的权限设计 这种模式下每一个操作都在数据库中有记录,用户是否拥有该操作的权限也在数据库中有记录,结构如下: 但是如果直接使用上面的设计,会导致数据库中的UserAction这张表数据量非常大,所以我们需要进一步设计提高效率,请看方案3   3.       基于角色和操作的权限设计 如上图所示,我们在添加了Role,和RoleACTION表,这样子就可以减少USERACTION中的记录,并且使设计更灵活一点。 但是这种方案在用户需求的考验之下也可能显得不够灵活够用,例如当用户要求临时给某位普通员工某操作权限时,我们就需要新增加一种新的用户角色,但是这种用户角色是不必要的,因为它只是一种临时的角色,如果添加一种角色还需要在收回此普通员工权限时删除此角色,我们需要设计一种更合适的结构来满足用户对权限设置的要求。   4.       2,3组合的权限设计,其结构如下: 我们可以看到在上图中添加了UserAction表,使用此表来添加特殊用户的权限,改表中有一个字段HasPermission可以决定用户是否有某种操作的权限,改表中记录的权限的优先级要高于UserRole中记录的用户权限。这样在应用程序中我们就需要通过UserRole和UserAction两张表中的记录判断权限。 到这儿呢并不算完,有可能用户还会给出这样的需求:对于某一种action所操作的对象某一些记录会有权限,而对于其他的记录没有权限,比如说一个内容管理系统,对于某一些频道某个用户有修改的权限,而对于另外一些频道没有修改的权限,这时候我们需要设计更复杂的权限机制。   5.       对于同一种实体(资源)用户可以对一部分记录有权限,而对于另外一些记录没有权限的权限设计: 对于这样的需求我们就需要对每一种不同的资源创建一张权限表,在上图中对Content和Channel两种资源分别创建了UserActionContent和UserActionChannel表用来定义用户对某条记录是否有权限;这种设计是可以满足用户需求的但是不是很经济,UserActionChannel和UserActionContent中的记录会很多,而在实际的应用中并非需要记录所有的记录的权限信息,有时候可能只是一种规则,比如说对于根Channel什么级别的人有权限;这时候呢我们就可以定义些规则来判断用户权限,下面就是这种设计。   6.       涉及资源,权限和规则的权限设计 在这种设计下角色的概念已经没有了,只需要Rule在程序中的类中定义用户是否有操作某种对象的权限。 以上只是分析思路,如果有不对的地方,请大家指正。 -----------------------------------

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享文档获得金币 ]
3 人已下载

下载文档

相关文档