用户系统权限设计

权限设计通常包括数据库设计、应用程序接口(API)设计、程序实现三个部分。

这三个部分相互依存,密不可分,要实现完善的权限管理体系,必须考虑到每一个环节可行性与复杂程度甚至执行效率。

我们将权限分类,首先是针对数据存取的权限,通常有录入、浏览、修改、删除四种,其次是功能,它可以包括例如统计等所有非直接数据存取操作,另外,我们还可能对一些关键数据表某些字段的存取进行限制。除此,我想不出还有另外种类的权限类别。

完善的权限设计应该具有充分的可扩展性,也就是说,系统增加了新的其它功能不应该对整个权限管理体系带来较大的变化,要达到这个目的,首先是数据库设计合理,其次是应用程序接口规范。

我们先讨论数据库设计。通常我们使用关系数据库,这里不讨论基于Lotus产品的权限管理。

权限表及相关内容大体可以用六个表来描述,如下:
1 角色(即用户组)表:包括三个字段,ID,角色名,对该角色的描述;
2 用户表:包括三个或以上字段,ID,用户名,对该用户的描述,其它(如地址、电话等信息);
3 角色-用户对应表:该表记录用户与角色之间的对应关系,一个用户可以隶属于多个角色,一个角色组也可拥有多个用户。包括三个字段,ID,角色ID,用户ID;
4 限制内容列表:该表记录所有需要加以权限区分限制的数据表、功能和字段等内容及其描述,包括三个字段,ID,名称,描述;
5 权限列表:该表记录所有要加以控制的权限,如录入、修改、删除、执行等,也包括三个字段,ID,名称,描述;
6 权限-角色-用户对应表:一般情况下,我们对角色/用户所拥有的权限做如下规定,角色拥有明令允许的权限,其它一律禁止,用户继承所属角色的全部权限,在此范围内的权限除明令禁止外全部允许,范围外权限除明令允许外全部禁止。该表的设计是权限管理的重点,设计的思路也很多,可以说各有千秋,不能生搬硬套说某种方法好。对此,我的看法是就个人情况,找自己觉得合适能解决问题的用。

先说第一种也是最容易理解的方法,设计五个字段:ID,限制内容ID,权限ID,角色/用户类型(布尔型字段,用来描述一条记录记录的是角色权限还是用户权限),角色/用户ID,权限类型(布尔型字段,用来描述一条记录表示允许还是禁止)

好了,有这六个表,根据表六,我们就可以知道某个角色/用户到底拥有/禁止某种权限。

或者说,这么设计已经足够了,我们完全实现了所需要的功能:可以对角色和用户分别进行权限定制,也具有相当的可扩展性,比如说增加了新功能,我们只需要添加一条或者几条记录就可以,同时应用程序接口也无须改动,具有相当的可行性。但是,在程序实现的过程中,我们发现,使用这种方法并不是十分科学,例如浏览某个用户所拥有的权限时,需要对数据库进行多次(甚至是递归)查询,极不方便。于是我们需要想其它的办法。使用过Unix系统的人们都知道,Unix文件系统将对文件的操作权限分为三种:读、写和执行,分别用1、2、4三个代码标识,对用户同时具有读写权限的文件被记录为3,即1+2。我们也可以用类似的办法来解决这个问题。初步的想法是修改权限列表,加入一个字段:标识码,例如,我们可以将录入权限标识为1,浏览权限标识为2,修改权限标识为4,删除权限标识为8,执行权限标识为16,这样,我们通过权限累加的办法就可以轻易的将原本要分为几条记录描述的权限放在一起了,例如,假定某用户ID为1,库存表对应的限制内容ID为2,同时规定角色类型为0、用户类型为1,我们就可以将该用户具有录入、浏览、修改、删除库存表的权限描述为:2,15,1,1。

确实很简单,不是吗?甚至还有更过激的办法,将限制内容列表也加上一列,定义好标识码,这样,我们甚至可以用简单的一条记录描述某个用户具有的对全部内容所具有的全部权限了。当然,这样做的前提是限制内容数量比较小,不然,呵呵,2的n次方递增起来可是数量惊人,不容易解析的。

从表面上看,上述方法足以达到实现功能、简化数据库设计及实现的复杂度这个目的,但这样做有个弊端,我们所涉及的权限列表不是相互独立而是互相依赖的,比如说修改权限,其实是包含浏览权限的,例如,我们可能只是简单的设置用户对库存表存取的权限值为录入+修改+删除(1+4+8=13),但事实上,该用户具有(1+2+4+8=15)的权限,也就是说,在这种方案中,13=15。于是当我们调用API询问某用户是否具有浏览权限时,就必须判断该用户是否具有对该数据表的修改权限,因此,如果不能在程序中固化权限之间的包含关系,就不能利用应用程序接口简单的做出判断。但这与我们的目的“充分的可扩展性”矛盾。

这个问题如何解决?我想到了另外一种设置标识码的方法,那就是利用素数。我们不妨将录入、浏览、修改、删除、执行的基本标志码定为2,3,5,7,11,当遇到权限互相包含的时候,我们将它的标识码设定为两个(或多个)基本标志码的乘积,例如,可以将“修改”功能的标志码定为3*5=15,然后将所有的权限相乘,就得到了我们需要的最终权限标识值。这样,我们在询问用户是否具有某项权限的时候,只需要将最终的值分解成质因子,例如,我们可以定义一个用户具有录入+修改+删除库存表的权限为 2*15*7=2*3*5*7,即表示,该用户具有了对库存表录入+浏览+修改+删除权限。

当然,对权限列表我们使用上述方法的前提是权限列表记录条数不会太多并且关系不是十分复杂,否则,光是解析权限代码就要机器忽悠半宿:)

针对 OA 系统的特点,权限说明: 权限系统中,权限通过模块 +动作来产生,模块就是整个系统中的一个子模块,可能对应一个 菜单,动作也就是整个模块中(在B/S 系统中也就是一个页面的所有操作,比如“ 浏览、添 加、修改、删除” 等)。将模块与之组合可以产生此模块下的所有权限权限组 为了更方便的权限的管理,另将一个模块下的所有权限组合一起,组成一个“ 权限组” ,也就 是一个模块管理权限,包括所有基本权限操作。比如一个权限组(用户管理),包括用户的 浏览、添加、删除、修改、审核等操作权限,一个权限组也是一个权限。 角色 权限的集合,角色与角色之间属于平级关系,可以将基本权限权限组添加到一个角色中, 用于方便权限的分配。 用户组 将某一类型的人、具有相同特征人组合一起的集合体。通过对组授予权限(角色),快速使 一类人具有相同的权限,来简化对用户授予权限的繁琐性、耗时性。用户组的划分,可以按 职位、项目或其它来实现。用户可以属于某一个组或多个组。 通过给某个人赋予权限,有4 种方式( 参考飞思办公系统) A . 通过职位 a) 在职位中,职位成员的权限继承当前所在职位的权限,对于下级职位拥有的权限不可继 承。 b) 实例中:如前台这个职位,对于考勤查询有权限,则可以通过对前台这个职位设置考勤 查询的浏览权,使他们有使用这个对象的权限,然后再设置个,考勤查询权(当然也可以不 设置,默认能进此模块的就能查询),则所有前台人员都拥有考勤查询的权利。 B. 通过项目 a) 在项目中,项目成员的权限来自于所在项目的权限,他们同样不能继承下级项目的权限, 而对于项目组长,他对项目有全权,对下级项目也一样。 b) 实例中:在项目中,项目成员可以对项目中上传文档,查看本项目的文档,可以通过对项 目设置一个对于本项目的浏览权来实现进口,这样每个成员能访问这个项目了,再加上项目 文档的上传权和查看文档权即可。 c) 对于组长,因为可以赋予组长一个组长权(组长权是个特殊的权限,它包含其他各种权 限的一个权限包),所有组长对于本项目有全权,则项目组长可以对于项目文档查看,审批, 删除,恢复等,这些权限对于本项目的下级项目依然有效。 C. 通过角色 a) 角色中的成员继承角色的权限,角色与角色没有上下级关系,他们是平行的。通过角色 赋予权限,是指没办法按职位或项目的分类来赋予权限的另一种方式,如:系统管理员,资 料备份员… b) 实例中:对于本系统中,全体人员应该默认都有的模块,如我的邮件,我的文档,我的 日志,我的考勤……,这些模块系统成员都应该有的,我们建立一个角色为系统默认角色, 把所有默认访问的模块的浏览权加入到里面去,则系统成员都能访问这些模块。 D. 直接指定 a) 直接指定是通过对某个人具体指定一项权限,使其有使用这个权限的能力。直接指定是 角色指定的一个简化版,为了是在建立像某个项目的组长这种角色时,省略创建角色这一个 步骤,使角色不至于过多。 b) 实例中:指定某个项目的组长,把组长权指定给某个人。 针对职位、项目组: 如果用添加新员工,员工调换职位、项目组,满足了员工会自动继承所在职位、项目组的权 限,不需要重新分配权限的功能。 用户管理 用户可以属于某一个或多个用户组,可以通过对用户组授权,来对组中的所有用户进行权限 的授予。一个用户可以属于多个项目组,或担任多个职位。 授权管理 将一个基本权限或角色授予用户用户组,使用户用户组拥有授予权限的字符串,如果角 色、职位、项目中存在相同的基本权限,则取其中的一 个;如脱离角色、职位、项目组, 只是取消用户用户组的中此角色、职位、项目组所授予的权限用户所拥有的权限是所有 途径授予权限的集合。管理员用户可以 查看每个用户的最终权限列表。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值