简单角色权限设计


   最近公司系统调整,前期因为需求的不稳定,所以角色权限这一块没有完全的确定一个固定方案,现在需要重新设计一套可用性比较广的的角色权限方案,再以此为基础对现有系统进行一定程度的改造。需要能满足一下几个目的:

1 能够对资源进行细颗粒度的控制(粗颗粒,即只控制到菜单、按钮、方法。细颗粒度控制到数据级别,比如同样是角色“”班主任“”,可见的学生都是自己班上的,无法看到别的班级的学生)

2 能够灵活配置:用户到角色可以多对多,角色到权限也可以多对多

3 角色授权:用户可以创建子角色,并对子角色进行授权,可以授权到细粒度级别,并选择被授权的时间段,但被授权角色的权限不能超过原用户的权限(一个角色是否能够创建子角色由系统管理员分配,创建的子角色的权限是不包含这个继续授权。如果一个用户有多个角色,能授权的功能范围是被管理员标为“允许授权”的部分。)这个功能主要用于临时授权,系统主要角色还是通过系统管理员设置(第三点需求思考后发现不同的业务场景下的具体授权模式区别可能会很大,所以暂时先不考虑在内,以后由具体的需求再进行改造)

 

  方案最核心的是资源表(权限表)的设计,以往的资源表对资源的控制方法是一个页面资源是数据库中的一条记录,或者更细一点,一个按钮是一条记录,这样做维护和扩展不是很方便,后期系统如果要统一扩展某一个操作类型(比如所有表单支持批量导出),修改的工作量会很大。或者是取消某一个角色在某一个功能域内的所有update权限,需要去对这个域内的资源进行完全遍历才能达成。代码写起来也很繁琐,容易出错。重新设计的资源表以页面资源为一个主体,系统所有资源都以这种方式管理,每一个页面会包含crud和一些其他的操作在内,为了方便管理对所以资源进行一个分级(不分级也没有影响):

0级为根资源,为所以1级资源的父资源(留作后期扩展)
1级资源为主菜单资源(菜单只有可见和不可见两种,所以只具有read操作)
2级资源为子菜单资源
3级及以后资源为页面资源(也可将子菜单的可见与否与页面资源的read权限进行合并)

添加新资源时,level为父资源的level+1

 

  每个资源都具有多个种类的操作权限,如果将一个权限作为一个字段不但管理不方便,而且也完全无法扩展,所以我将所以权限合并到一个字段,统一管理。字段用二进制显示,预先设置为小于256,也就是最大表示11111111(这个可以灵活扩展),具体设计如下:

从右边数第1位表示资源是否具有read的功能,1表示有,0表示无;
从右边数第2位表示资源是否具有create的功能,1表示有,0表示无;
从右边数第3位表示资源是否具有update的功能,1表示有,0表示无;
从右边数第4位表示资源是否具有delete的功能,1表示有,0表示无;
从右边数第5位表示资源是否具有设置数据范围的的功能,1表示有,0表示无;(如果一个资源的管理权限是带范围的,就像这一位设为1,比如上面班主任看班级成员信息的页面)

举例:00001111 表示这个资源具有crud权限,它可能是一个常用的信息管理页面。00000001表示这个资源只具有读的功能,它可能是一个新闻页面

这样做的好处是可以非常方便的了解一个资源所具有的权限。修改和扩展也很方便,比如如果要使整个系统对某一个资源的某一种操作关闭,只需将其中表示该操作的字符位从1变为0就行了。


如果资源有其他的权限类型需要管理,可以继续添加字符位,比如常用的批量导出数据,在页面添加这个操作按钮和后台代码后,我们将这个操作控制字符位放在从右边数第六位,可以并不影响以前的权限功能;包括范围设置也可能不止一个维度,如果其他资源有从另一个维度来进行范围划分(比如一个部门内部继续按小组来划分),也可以继续增加范围权限的字符位。

备注: 这个资源表是从整个系统资源来考虑,所以要保持系统的一致性,比如我们设定第一个字符位为read权限,那么整个系统的所以资源都要按照这个规则来,全部保持一致。如果有新的操作类型,可以新增定义,但不要修改原来定义的含义。

 

  配合资源表的是角色-资源表,角色-资源表的权限字段定义方案还是按照资源表中的定义,但是是资源表的子集,比如资源表中某一个资源的操作权限是00000111,那么在角色-资源表中对应的值可以是00000111,或者00000101,而不能是00001111;因为该资源定义时就不包含删除操作。1表示该角色对于该操作具有权限,0表示该角色对于该操作不具有权限。

  采取这个二进制方式最大的好处是能方便的解决权限的合并问题,比如一个人M具有两个角色A,B,这两个角色对资源X分别具有0000101和00001011的操作权限,那么我们通过“或”的操作就能快速将两个甚至多个角色的权限合并,此例中合并的后的值为00001101,表示用户M对资源X具有读、修改和删除的权限。代码中是根据字符位来判定权限,写业务逻辑的员工不需要操心这个权限的来源是一个角色还是多个角色。很好的进行了抽象。

 

  资源和权限表的设计只能解决目的二,对于目的一还是没有解决。考虑到实际的应用场景一般对于数据范围的划分是针对同一角色同一职责,比如所以班主任的职责是一样的,所以从设计上并不适合给它每一个班主任划分不同角色,那么我们就用同一角色来管理他们的操作,另外再用一张表来维护他们的数据范围。将这个范围控制给到用户,而不是角色。利用现有的范围信息表(比如班级表,部门表等等),给需要的用户分配一个范围ID(班级ID),在简单的业务情况下,可以直接将班级ID作为用户表的一个字段,当我们需要修改用户的工作范围时,只需要更改他的班级ID就行了,而不需要修改他的角色类型。这种设计模式也更符合我们业务的实际情况,大多数工作调动很多都是平级调动,比如从一个班级调到另一个班级,而工作性质和权限是不变的。

所有用到的表的关系如下:

 

 

 

 

 总结:目前这种设计只是适用于简单的常用权限设计,应该还有更优化的方法。并且随着业务情况的变化还应该有更多的变化,以后遇到再补充。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM