基于web信息管理系统的权限设计分析和总结

这里讨论的权限只涉及到信息管理系统里面的权限管理,超出此范围的权限管理暂不涉及。

1、权限的应用对象

上面我们已经定义了权限的范围,就是信息系统管理里面的表单操作,那么权限的应用对象就是表单,更进一步说,就是表达表单内容的web管理页面。

2、权限的分类

一个页面的权限范围分为以下几种,也可以叫做基本权限单位。

  操作权限:操作权限是一种页面级别的权限,也可以叫做页面权限。包括以下几种

  •  新增
  •  修改
  •  删除
  •  查询

 在此基础上还可以进行更加详细的一些分类,比如查看他人记录的权限,修改他人记录的权限等。这部分也可以使用下面的记录权限来实现。

     按钮权限:针对页面上按钮的权限管理,包括

  • u 是否可见
  • u 是否可用

 有时候,我们可以把按钮权限看作为字段权限。

     字段权限:字段在页面的不同状态(新增,修改,查询)下面的各种状态管理。包括

  •  是否可见
  •  是否可修改

    记录权限:记录权限是指用户对某些记录的查看和修改权限。比如客户关系管理系统中,不同界别的系统用户可以看到不同的记录,例如上司可以看他所有下级员工的客户列表等。

3、权限的实现模型

上面的权限分类大概对涉及到页面元素的权限进行了一个比较全面的概括。另外一个问题就是权限管理的实现模型。在大部分的系统中都是用的基于角色控制模型的权限管理。在这样的系统中,创建一系列的角色,然后把基本权限单位分配给这些角色,再把角色分配给用户,这样用户登录系统后,就根据当前用户所拥有的角色可以定位出权限。

 在针对信息管理系统中,权限模型有自己的特色,除了角色的概念以外,还有表单权限的概面。第一节里面所讨论的各种权限基本单位不但可以应用到角色上,也可以应用到表单上。

对于应用到表单上的基本权限单位,我们叫做表单的固有权限属性(静态权限)。对于应用到角色上的基本权限单位,我们叫做角色权限属性(动态权限)。用下图来表示:

 

 

 根据上面的模型,一个用户登录到系统中后,得到某一个表单的权限就和这个表单的固有权限属性和这样用户所拥有的角色有关。

4、权限的计算方式

用户登录后对一个表单进行操作,静态权限只有一个,即表单本身的权限属性,动态权限可以有多个,即用户可以同时属于多个角色,这些角色在这个表单上都有不同的动态权限。用户对这个表单所能进行的操作是由这个动态权限和静态权限的综合作用决定的。进行权限判断分为两个步骤:

1 动态权限组合:根据用户所属的角色的权限分析得到最终的动态权限集合。

2 动态权限和静态权限的组合:利用得到的动态权限集合再和静态权限进行综合分析得到用户的最终权限。

 在动态权限和动态权限进行组合判断,以及动态权限和静态权限进行组合判断的时候,根据权限类型的不同,使用不同的组合判断方法

对于 操作权限,分为两种组合方法:

          或操作:或操作认为,两个层次的权限单位进行比较,只要其中一个权限单位认为“可以做”,那么组合权限结果就是“可以做”。例如对于“增加”这个操作权限,如果角色A设置为可以增加,角色B设置为不可以增加,那么综合的结果就是 可以进行 “增加”

          与操作:与操作认为,两个层次的权限单位进行比较,只要其中一个权限单位认为“不可以做”,那么组合权限结果就是“不可以做”。例如: 对于“增加”这个操作权限,如果角色A设置为可以增加,角色B设置为不可以增加,那么综合的结果就是 不可以进行 “增加”

 对于字段权限 和 记录权限 只有一种组合方法:

          权限并集:也就是说组合的结果是这两种层级的权限单位控制范围的一个相交的结果。例如:对于角色A,他在表单F上的的只读字段为(a,b,c,d),角色B在表单F上的只读字段为(c,d,e,f),那么角色A和角色表的相交结果就是只读字段集合(a,b,c,d,e,f)。

 下面两张表显示了不同的权限层次,不同的权限类型在进行权限比较时选择不同的比较方法:

不同的角色之间进行权限比较:

 

角色B-操作权限

角色B-字段权限

角色B-记录权限

角色A-操作权限

或操作

 

 

角色A-字段权限

 

并集

 

角色A-记录权限

 

 

并集

 当有多个角色权限是,列入有角色A,B,C,D,先对A,B做计算,然后把计算结果和C进行计算,依次类推。

 动态权限和静态权限进行权限比较:

 

动态权限-操作权限

动态权限-字段权限

动态权限-记录权限

静态权限-操作权限

与操作

 

 

静态权限-字段权限

 

并集

 

静态权限-记录权限

 

 

交集

看过基于web信息管理系统的权限设计分析和总结(理论)的一些网友问道,能不能给出这个权限模型的实现,其实模型是一个解决给定问题的理论指导,具体的实现可以有多种方式,可能根据您的项目的实际情况有所不同,这里给出一个是基于sql server数据库的实现。这里提到的只是一些基本的权限信息,您当然可以扩展更多的权限信息。

 首先需要定义的是基本权限单位的数据库模型,用下表来表示:(这个表不是独立存在的,而是合并到表单信息表 和 角色权限表中)

权限类型

字段名称

类型

意义

操作权限

AddAction

bit

新增

ModifyAction

bit

修改

DeleteAction

bit

删除

SearchAction

bit

查询

字段权限

(字段之间以逗号 , 分割)

ReadOnlyColumnsOnAdd

Nvarchar(1000)

只读字段(新增)

HiddenColumnsOnAdd

Nvarchar(1000)

隐藏字段(新增)

ReadOnlyColumnsOnModify

Nvarchar(1000)

只读字段(修改)

HiddenColumnsOnModify

Nvarchar(1000)

隐藏字段(修改)

HiddenColumnsOnSearch

Nvarchar(1000)

隐藏字段(查询)

纪录权限

(一段表示权限范围的语句,在本实现中,就是一个sql语句的片断)

 

ReadOnlyRecords

Nvarchar(1000)

只读纪录

HiddenRecords

Nvarchar(1000)

隐藏纪录

 接下来是表单信息表,表单信息表有一些基本的表单信息,例如表单名称等,同时表单信息表也拥有以上的基本权限数据,这些权限信息构成了表单的固有权限属性(静态权限),一个简单的表单信息表如下所示:

表单信息表:Forms

 

字段名称

类型

意义

 

 

FormID

Nvarchar(100)

表单ID

FormName

Nvarchar(100)

表单名称

AddAction

bit

新增

表单的固有权限属性

(静态权限)

ModifyAction

bit

修改

DeleteAction

bit

删除

SearchAction

bit

查询

ReadOnlyColumnsOnAdd

Nvarchar(1000)

只读字段(新增)

HiddenColumnsOnAdd

Nvarchar(1000)

隐藏字段(新增)

ReadOnlyColumnsOnModify

Nvarchar(1000)

只读字段(修改)

HiddenColumnsOnModify

Nvarchar(1000)

隐藏字段(修改)

HiddenColumnsOnSearch

Nvarchar(1000)

隐藏字段(查询)

ReadOnlyRecords

Nvarchar(1000)

只读纪录

HiddenRecords

Nvarchar(1000)

隐藏纪录

 下面就是角色表了,角色表相当简单,只包含一个角色名称就可以了:

角色表:Roles

字段名称

类型

意义

RoleID

Nvarchar(100)

角色ID

RoleName

Nvarchar(100)

角色名称

 定义好了角色表,接下来就是角色权限了,就是角色在每个表单上的权限表现形式,当前这个表就需要跟角色以及表单有关了,具体的结果如下:

角色权限表: RolePurview

字段名称

类型

意义

 

 

 

RolePurviewID

Nvarchar(100)

主键

FormID

Nvarchar(100)

表单ID

外键,关联到表单信息表的FormID

RoleID

Nvarchar(100)

角色ID

外键,关联到角色表的RoleID

AddAction

bit

新增

表单的角色权限属性

(动态权限)

ModifyAction

bit

修改

DeleteAction

bit

删除

SearchAction

bit

查询

ReadOnlyColumnsOnAdd

Nvarchar(1000)

只读字段(新增)

HiddenColumnsOnAdd

Nvarchar(1000)

隐藏字段(新增)

ReadOnlyColumnsOnModify

Nvarchar(1000)

只读字段(修改)

HiddenColumnsOnModify

Nvarchar(1000)

隐藏字段(修改)

HiddenColumnsOnSearch

Nvarchar(1000)

隐藏字段(查询)

ReadOnlyRecords

Nvarchar(1000)

只读纪录

HiddenRecords

Nvarchar(1000)

隐藏纪录

 

当然要完成整个模型,还需要用户信息表以及用户角色表

用户信息表:Users

字段名称

类型

意义

UserID

Nvarchar(100)

用户ID

UserName

Nvarchar(100)

用户名称

 

用户角色表:UserInRoles

字段名称

类型

意义

UserInRoleID

Nvarchar(100)

主键

UserID

Nvarchar(100)

用户ID

外键,关联到用户表的UserID

RoleID

Nvarchar(100)

角色ID

外键,关联到角色表的RoleID

 

到目前为止,我们完成这个模型所需要的表都出场了,下面的图表示了他们之间的关系:

 

 

 

在下节中将实现具体的权限的计算公式。XZZ

首先需要一个存储过程来实现计算用户在表单上的权限,这个存储过程接受两个参数,用户ID和表单ID,在这个存储过程里面使用一条sql语句来计算用户在表单上的权限,如下所示:

 Code

-- =============================================

--计算用户对表单的权限

-- =============================================

create PROCEDURE [dbo].[sp_GetUserPurveiewOnMenu]

    @userID nvarchar(100) ,--用户ID

    @formID nvarchar(100) --表单ID

AS

BEGIN

SELECT rp.formID,

       u.userID,

       --计算记录权限:只读记录

      dbo.fun_Purview_GetRecordPurview(u.userID,rp.formID,'ReadOnlyRecords') as ReadOnlyRecords,

       --计算记录权限:隐藏记录记录

       dbo.fun_Purview_GetRecordPurview(u.userID,rp.formID,'HiddenRecord') as HiddenRecord,

 

       --计算字段权限:只读记录(新增)

       dbo.fun_Purview_GetColumns(u.userID,rp.formID,'ReadOnlyColumnsOnAdd') as ReadOnlyColumnsOnAdd,

       --计算字段权限:隐藏记录(新增)

       dbo.fun_Purview_GetColumns(u.userID,rp.formID,'HiddenColumnsOnAdd') as HiddenColumnsOnAdd,

       --计算字段权限:只读记录(修改)

       dbo.fun_Purview_GetColumns(u.userID,rp.formID,'ReadOnlyColumnsOnModify') as ReadOnlyColumnsOnModify,

       --计算字段权限:隐藏记录(修改)

     dbo.fun_Purview_GetColumns(u.userID,rp.formID,'HiddenColumnsOnModify') as HiddenColumnsOnModify,

       --计算字段权限:隐藏记录(查询)

       dbo.fun_Purview_GetColumns(u.userID,rp.formID,'HiddenColumnsOnSearch') as HiddenColumnsOnSearch,

       --计算操作权限:新增

       (CASE

           WHEN (SUM((CAST((CASE f.AddAction WHEN 0 THEN 0

                         ELSE rp.AddAction

                         END) AS int)))) > 0 

           THEN cast(1 as bit)

           ELSE cast(0 as bit)

           END) as AddAction, 

       --计算操作权限:修改

       (CASE

           WHEN ( SUM((CAST((CASE f.ModifyAction WHEN 0 THEN 0

                      ELSE rp.ModifyAction

                     END) AS int))) ) > 0 

           THEN cast(1 as bit)

           ELSE cast(0 as bit)

           END) as ModifyAction,

         

       --计算操作权限:删除

       (CASE

           WHEN ( SUM((CAST((CASE f.DeleteAction WHEN 0 THEN 0

                         ELSE rp.DeleteAction

                          END) AS int)))) > 0 

           THEN cast(1 as bit)

           ELSE cast(0 as bit)

           END) as DeleteAction,

       --计算操作权限:查询

       (CASE

           WHEN ( SUM((CAST((CASE f.SearchAction WHEN 0 THEN 0

                         ELSE rp.SearchAction

                         END) AS int)))) > 0 

           THEN cast(1 as bit)

           ELSE cast(0 as bit)

           END) as SearchAction

           

      FROM users u,

            userinroles ur,

            RolePurview rp,

            forms f

         WHERE u.userID = ur.userID

                 AND ur.roleID = rp.roleID

                 AND rp.formID = f.formID

                 AND u.userID = @userid

                 AND f.formID = @formID

         GROUP BY rp.formID,u.userID

END

 在这个存储过程里面,有两个用户函数,分别用于计算字段权限和记录权限。

用于计算字段权限的函数是fun_Purview_GetColumns,这个函数接受三个参数,分别是用户ID、表单ID和字段权限类型,具体如下所示:

 Code

-- =============================================

-- 计算字段权限

-- =============================================

create FUNCTION [dbo].[fun_Purview_GetColumns]

(

    @userID nvarchar(100),--用户ID

    @formID nvarchar(100),--表单ID

    @columnType varchar(50)--字段权限类型

)

RETURNS nvarchar(2000)

AS

BEGIN 

    declare @columsID nvarchar(4000),@tem nvarchar(1000),@c cursor 

    set @columsID=''

    set @tem = ''

    if @columnType = 'ReadOnlyColumnsOnAdd' -- 计算只读字段集合(新增)。对于其他字段集合类似

    begin 

       set @c = cursor for   select    ReadOnlyColumnsOnAdd from forms where formID=@formID

                            union

                            select   ReadOnlyColumnsOnAdd from RolePurview where roleID in(

                            select roleID from UserInRoles where userID=@userid

                            )   

       open @c

       fetch next from @c into @tem

       while @@fetch_status =0

       begin 

           if @tem is not null

           begin 

              set @columsID = @columsID +','+ @tem

                  end

           fetch next from @c into @tem    

       end

       close @c

       deallocate @c

    end 

return @columsID

END

 用于计算记录权限的函数是fun_Purview_GetRecordPurview,这个函数接受三个参数,分别是用户ID、表单ID和记录权限类型,具体如下所示:

Code

-- =============================================

--计算记录权限

-- =============================================

alter FUNCTION [dbo].[fun_Purview_GetRecordPurview]

(

    @userid int,--用户ID

    @formID int ,--表单ID

    @recordPurviewType varchar(100)--记录权限类型

)

RETURNS nvarchar(4000)

AS

BEGIN 

    declare   @recordPurviewSql nvarchar(4000),@c2 cursor,@sql nvarchar(4000),

           @formRecordPurviewExpression nvarchar(4000)

    set @recordPurviewSql = ''

    set @sql = '' 

     if @recordPurviewType ='ReadOnlyRecords'--计算只读记录,对于隐藏记录类似

    begin

       set @c2 = cursor for select ReadOnlyRecords from RolePurivew where roleID in( select roleID from UserInRoles where userID=@userid

                         )   and formID=@formID

 

       open @c2

 

       fetch next from @c2 into @sql

       while @@fetch_status =0

       begin 

           if @sql is not null and @sql<> ''

           begin

              --对于角色之间的记录权限,使用并集

              set @recordPurviewSql = @recordPurviewSql +'('+@sql+')' + ' or '

              end

           fetch next from @c2 into @sql   

       end

       close @c2

       deallocate @c2 

       if len(@recordPurviewSql) > 3

       begin

           set @recordPurviewSql = substring(@recordPurviewSql,1,len(@recordPurviewSql)-3)

       end

       select @formRecordPurviewExpression= ReadOnlyRecords from forms where formID=@formID

 

      if @recordPurviewSql is not null and @recordPurviewSql <>''

       begin

           set @recordPurviewSql = '('+@recordPurviewSql+')'

           if @formRecordPurviewExpression is not null and @formRecordPurviewExpression <>''

              --对于角色和表单的记录权限,使用交集

              set @recordPurviewSql = @recordPurviewSql +' and ('+@formRecordPurviewExpression+')'

       end

       else

       begin

           if @formRecordPurviewExpression is not null and @formRecordPurviewExpression <>''

              set @recordPurviewSql = '('+@formRecordPurviewExpression+')'

       end

    end

     return @recordPurviewSql

END 

 

使用上面的函数就可以计算用户在表单上的权限了。

另外,您也可以对此权限模型进行扩展,比如您可以对角色设置一个角色的权限计算类型属性.

如果此角色是悲观型的,那么此角色和其他角色进行权限计算是,使用最小的权限集合。具体来说对于字段权限,使用与操作,对于字段权限和记录权限,使用交集。如果此角色是乐观型的,那么此角色和其他角色进行权限计算是,使用最大的权限集合。具体来说对于字段权限,使用或操作,对于字段权限和记录权限,使用并集。

在具体的项目实践中,为了提高性能,可以设置一些缓存,例如可以把上面的计算结果缓存到一个数据表里面,作为一级数据缓存。在程序中,还可以使用二级缓存在内存中保存用户的权限,当然这样做在提高性能的同时,也增加了程序的复杂度和数据的冗余,需要处理更多的地方。

posted @ 2012-05-26 19:25  齐鲁青未了  阅读(399)  评论(0编辑  收藏  举报