您的位置:首页 > 其它

MIS系统中的权限设计

2015-09-03 11:58 369 查看

MIS系统中的权限设计

MIS系统中的权限设计
版本记录

引言

数据库设计
功能权限
模块表设计

权限表设计

菜单表设计

角色模块权限表

方法权限表

资源权限和组织可见性
组织可见性

用户和组织关系

私有资源可见性

共享资源的可见性控制

角色和属性可见性

平台设计方式
组织和角色可见性

版本记录

文档版本更新时间内容
1.0.12015-9-13增加共享资源可见性控制内容
1.02015-9-3初始版本

引言

在MIS系统中,很常见的一个问题就是权限的设计。而权限的设计在终端的表现上又区分为对资源的权限,对菜单可见性的控制,对功能使用的限制等。有些系统中会对按钮,对菜单,对功能,对资源都分别进行设置。这样不仅实际上使用不方便,而且对于后台设计而言也是不容易的。因此,今天来从另一种思路来进行一个权限系统的设计。

在权限系统的设计中,权限设计分为两大块,一块是功能权限,一块是资源权限。

- 功能权限:

功能权限指的是针对某一个功能,某个用户是否可以使用。在界面上的表示形式则为该菜单用户是否可见(比如左侧的导航菜单,比如工具栏的一些添加,删除等功能按钮),以及在非法调用该功能API时是否会被拦截。

- 资源权限

资源权限指的是对于某一个资源(文档,项目表之类的东西),某个用户是否可以访问,是否可见,是否可以操作等。

本文的权限设计就从这两个点出发,进行设计。

整个权限系统的实现,是一个从数据库设计到代码设计相互配合的过程。当然,代码上的设计相对简单,数据库的设计则是其中的重点,数据库的设计决定了代码将要如何配合来实现整体的权限思想。

数据库设计

功能权限

在设计功能权限之前,首先需要明确的一点就是对于每一个功能(也就是程序里的对应方法),都有一个权限对应,而用户使用该功能的时候就需要验证该功能是否在用户的权限列表中。为此我们使用一种ACL的验证方式。

ACL验证模式

将一个二进制的数字表示为一个功能的权限。比如读取用户的功能的权限是0x00000001,请注意,这个权限数字是针对具体模块有效的。然后A用户自身的权限集合是0x01010101011。那么验证A是否可以读取用户,可以使用功能的权限数字与用户的权限集合进行“与“运算。如果运算后的结果与功能的权限数字相等,则意味着具备该权限。此种方法具备速度快而且同时验证多个权限组合(验证权限组合的方法先将权限组合进行”并“运算,然后再与用户的权限列表进行”与“运算)。

基于ACL的验证方式,可以使我们快速的完成对一个功能进行权限验证。而这个验证的核心思想就是为一个用户分配每一个功能模块的权限,而每一个具体的功能必然都隶属于某一个模块,并且要求具体的权限。将这个功能要求的模块权限与用户持有的权限集合进行比对即可知道用户是否有权使用该功能。下面进入到具体的数据库设计。

模块表设计

模块表用来存储系统中不同的模块,用于对功能进行大粒度的区分

id模块名称
1用户管理
2角色管理

权限表设计

权限表用来存储具体每一个模块下面都有什么样的权限,以及每一个权限自身对应的权限数字

id模块功能名称权限
11搜索用户0x00000001
21增加用户0x00000010
31删除用户0x00000100
41更新用户0x00001000
52搜索角色0x00000001
62增加角色0x00000010
72删除角色0x00000100
这个表的含义就是每一个模块下面都有的具体的功能,并且每一个功能所对应的权限数字。需要注意的是,同一个模块下,每一个功能所使用的bit位置必须是不同的。这样才能做到有效的区分。

例子:

如果一个用户拥有”用户管理”模块的搜索用户和增加用户的权限,则该用户该模块持有的权限为0x00000011.也就是两个功能的权限的并运算结果。

菜单表设计

在权限管理中,一个很重要的终端效果就是对于没有特定权限的用户,菜单是隐藏的。一般而言,菜单包含左侧的导航菜单,中央显示区域的工具栏菜单。对于这种需求,就需要有一个菜单表进行能够显示的拦截。

Id菜单名称父菜单id对应模块所需权限菜单位置菜单顺序
1用户管理010x00000001左侧菜单0
2增加110x00000010工具栏菜单1
3删除110x00000100工具栏菜单2
4编辑110x00001000工具栏菜单3
5查看详细信息110x00010000工具栏4
6角色管理020x00000001左侧菜单1
7增加620x00000010工具栏2
8删除620x00000100工具栏3
在不同的位置需要抽取不同的菜单,这一点可以通过菜单位置来进行。并且通过父菜单id,就可以形成菜单树

比如需要展开左侧的导航菜单树时,只需要查询出所有的左侧菜单,并且按照权限(也就是并运算后等于菜单权限自身的),将不可见的删除结合父菜单id就组合成了菜单树。

如果一个菜单不需要权限就能显示,那么只要将该菜单的权限数字定为0即可

在上表中可以看到,工具栏菜单的父菜单都是左侧菜单。这里的父菜单作用不是用来生成菜单树。一般,左侧导航菜单点击后,都会有一个中央区域用来显示具体的资讯内容。而在该页面,工具栏要显示什么菜单,就由这个导航菜单下的子菜单,也就是工具栏菜单来决定。

例子:

比如用户对于用户管理的权限是0x00000011,则用户点击用户管理后,在该页面只能看到增加一个按钮

角色模块权限表

在ACL的设计方式中,用户的权限粒度只设计到模块这一层,但这其实已经足够使用。用户对每一个功能的权限判断,实际上就是该功能所需要的模块权限,和用户持有的模块权限的对比判断。

而每一个角色所拥有的权限则是通过角色模块权限表来确定的,也就是需要确定对于每一个模块,角色拥有什么样的权限。

这里权限设计采用一个取巧的方式,以KV方式存储。权限中使用字符串来表示。每个模块用
,
区隔,每个内容中key是模块id,value是角色对该模块权限。kv以
:
区隔

Id角色id权限
111
通过角色模块权限表,就能完全确定角色的权限。

那么如何为每一个角色进行权限信息的生成呢。可以在编辑角色的时候,使用一个树状菜单来表示所有可以编辑的权限。然后通过菜单传递权限表中的项的id过去即可。

这里需要特别注意并且在任何方面都需要遵守的是一个授权原则,如下。

角色是由具备创建角色权限的用户创建的。那么该角色的角色权限不能超过创建者本身的权限。

方法权限表

在权限系统中,每一个方法都有一个权限对应(无权限要求的方法,其权限数字为0)。这个权限信息可以以注解的方式写在源代码上,也可以记录在数据库中,因为一般方法的所需权限信息是不会更改的,所以注解方式写在代码里通过aop进行读取和判断是一种比较可行的方式。而如果要设计在数据库里,一般表结构如下

id方法名模块id权限数字
1UserAction.get10x00000010
2UserAction.delete10x00000100
在判断方法是否允许被用户调用的时候,使用方法自身需求的权限数字找到用户对应模块的权限数字,两者进行与操作以确定是否可以访问。

资源权限和组织可见性

在一些系统中存在资源权限的概念。比如A公司的老总可以查看该公司下的所有资料,而A公司下的B部门的部门经理只能查看B部门下的资料,而B部门下的C项目项目经理只能查看该项目的资料。还比如其他部门只能查看本部门的人事信息,而人事部门可以查看全公司的人事信息等等。在这些系统中均存在对资源可见性控制的要求。而资源权限就是为了处理资源可见性的问题。

组织可见性

一般认为,子组织的资源对父组织是可见的。而不同的平行组织之间的信息是无法直接共享查看的。由此可见组织关系是很重要的。首先设计组织关系表。

Id组织名称父组织id
1公司0
2开发部1
3设计部1
4人事部1
组织间除了上下级关系外,还有一种管理或者可见性的管理。比如人事部门对全公司都具有人事信息可见性。所以还需要额外设计一个组织可见性表。这个表的数据在编辑的时候,可以选择的组织只能是该用户所在组织,子组织,可见组织之中。

Id组织id可见组织id
141,2,3
所以在某个组织下的用户的可见性就由组织的上下关系和组织可见性管理.

用户和组织关系

用户是在组织之中,用户一个时刻只能属于一个组织(有时候一个用户拥有多个组织的身份信息,一般是登陆的时候指定)。组织不存储用户信息,用户和组织是多对一关系。

私有资源可见性

资源的权限其实就是资源可见性的表述。针对文档,通讯录,信息等,将其抽象认为是一种资源。那么这种资源应该存在对某一个组织的从属信息。因为某一个资源是属于某一个组织的。这里的资源表通过资源类型进行划分,但是在实际的设计中为了方便查询,可以将资源表设计很多份。不同类型的资源都各自设计一张表。

Id资源名称父资源id所属组织id资源类型
1Demo开发项目01项目
2开发文档111文档
3开发文档211文档
4视觉设计项目01项目
5设计文稿141文档
6设计文稿241文档
当用户创建一个资源的时候,该资源默认属于该用户所在的部门。如果需要更改,只可以更改为该用户所在部门的子部门。比如部门经理可以创建一个属于项目的文件,但是项目经理无法创建属于部门的文件。

当用户需要查询的时候,只可以查询自身组织,或者子组织,或者可见性组织下的资源。这样就做到了对资源可见性的控制。

共享资源的可见性控制

有些时候,希望一些资源是有限共享的,比如一些资料是某一个部门以及其所有的子部门都可见,或者有些新闻希望是公司可见。这种资源和私有的资源不同,私有资源只允许自身或者上级查看。而共享资源往往是事先指定的观看范围的人员可以观看。这种需求需要设计一张共享资源表。

Id资源名称父资源id所属组织id资源类型可见组织id
1开发文档111文档0
2开发文档111文档1
3设计文稿141文档0
4设计文稿141文档1
通过可见组织id,来限定资源的可见范围。这种资源的可见性只受共享资源可见性表的约束。在查询此类资源时,查看自己的id是否是在可见组织id中即可。在创建或者编辑一个共享资源的时候,可以指定可见的组织id。这样后台需要根据每一个可见的组织id来确认是否是已经存在的数据,以进行修改或者新增操作。

在实际的操作中,每次都进行组织可见性选择是比较繁琐的事情,可以创建一些群组,群组中都是事先包含好的组织id,将可见性由具体的组织替换成对应的群组可以在操作上提升便捷性,但是后台的处理流程是相同的。

角色和属性可见性

在一些系统设计中,存在着对不同的用户对同一份资源的不同字段可见性的控制要求。比如在CRM系统中,有一些用户在查看用户信息时,是无法查看用户的联系方式等要求。在这种情况下,就需要建立一个角色和字段可见表。

id角色id属性名称属性模块
11nameuser
21ageuser
通过这个表,就可以对一些资源中的字段进行可见性控制。但是这种设计是一种固化设计,也就是哪些资源需要可见性控制是定义好的。而非系统在使用过程中可以自定义。如果需要做到使用过程中的自定义,则程序方面和数据库方面需要做额外的其他工作。比如需要有一个资源和其字段的数据字典表。并且定义一个资源是否需要可见性控制的表。程序在执行查看的时候需要首先查询该资源是否需要可见性控制,如果需要的话,则将查询该角色对该资源的可见字段,然后才能执行对应的查询。

平台设计方式

组织和角色可见性

在一般的系统中,角色和组织是没有关系的,整个大系统使用一套角色体系。在选择角色时,所有的角色都是可见的。但是也存在一种需要,每一个组织需要创建自己的角色。平行组织创建的角色互不可见。

那么这个时候就需要一个组织和角色的对应表。并且最初的用户和最大的超管是系统中固有存在的。而具备创建角色权限的用户所创建的角色的权限不会超过该用户本身。此时角色也可以认为是资源,同样遵循子组织的角色父组织可见,平行关系组织之间角色不可见。角色组织表设计如下

id角色id组织id
111
221
在上述的表设计中,所有的组织都在一张表中,并且呈现树关系。但是有的时候希望一些具备明显特征的组织是区分开设计的,比如在平台设计的时候。平台的组织和入驻平台机构的组织有很大区分。

参考电商平台。电商平台自身也有很多角色进行不同的操作。而在电商平台入驻的这些商家也会有自身的创建角色的需求,并且商家自身也会有需要分配角色和用户的需求。在这种时候,将电商平台的组织和商家的组织放在同一张表中作为上下级组织关系也是可以的。但是放在不同的表中显然是会更加合理一些。

在这样的情况下,可以设计两张组织表,两张角色表。分别对应平台的组织,入驻平台的机构。平台中的超管角色可以新建入驻机构的信息,并且新建一个入驻机构的超管。换言之,有平台超管和机构超管两类。后者的权限只能到达机构级别,这个可以在建立机构超管时由程序限定。

这样在程序设计上就有两套管理系统,平台管理和机构管理。不同的登录界面查询不同的组织和角色表。

以平台为例,平台管理员新建机构时可以先新建机构组织本身,然后创建机构超管,将机构超管的组织设置为该机构。即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: