zoukankan      html  css  js  c++  java
  • 关于用户角色权限管理的探讨

    用户权限管理是我们在做应用时经常遇到的问题,但是我们是不是曾经对它做过比较深入的分析呢?不同的系统中的用户管理是不是可以抽象出一个通用的模型呢?    
       
      我们先来看一个最普通的例子:论坛。   为了便于分析,论坛的用户我们简化成三类:普通用户和版主。    
       
      以为例,sharetop是java版的版主,所以他登录的过程是这样:    
       
      登录(普通用户)->进入Java版(版主)->进入C++版(普通用户)->回到Java版(版主)    
       
      从现象上分析,在切换不同页面的时候,角色发生了改变,是吧?对应上面的过程,在sharetop登录后用RID来记录他的当前角色。   那它的变化就是    
       
      User->Sysop->User->Sysop。  
       
      于是,我们要解决的问题是:如何决定这个RID的变化?    
       
      if(   BlockID   is   java   &&   my.name   is   sharetop   )   my.RID=sysop;   else   my.RID=user;    
       
      那第二个问题是:这个IF语句是如何产生出来的?    
       
      我们在数据库中建立这样一个表role_table:    
       
      UID   RID   BID    
      sharetop   sysop   java    
      sharetop   user   c++    
       
      于是,我们根据这个表的内容去生成这个判断语句,上面的代码改成:    
       
      select   RID   from   role_table   where   BID=current.BlockID   and   UID=my.name;   my.RID=   selected   RID;    
       
      我们再优化一下,其它普通用户实在没必要记录,所以上表只需记录是sysop的用户的UID和BID即可。   命名为bolck_sysop_table  
       
      UID   RID   BID    
      sharetop   sysop   java    
      yanchang   sysop   jsp    
       
      (*)注意:我给出的表都只是逻辑结构并非真正的物理结构:),比如这两个字段可能被放在block_table中,而不是用一个独立的表来保存。下同。    
       
      RID可以保存在session中或是用有状态会话Bean来处理,只在每个版区的入口页面加入角色变化的验证代码,后面的页面即使用session中的RID值。同样,如果加上帖主的角色,唯一的区别在于验证代码应存在于显示帖子的页面,使用RID的页面也只有显示帖子的页面了。    
       
      在这个例子中我们看到这么一个现象:普通用户覆盖了全部的版区,在这个大集合里有一些子集,如java版版主、C++版版主等等。每个版主都是普通用户这个超类的某个子类,是具有特殊权限的普通用户。    
       
         
      问题是不是得到了解决?看起来好象是的:)   OK,那我们来看另一个复杂一些的例子吧。    
       
      我们有一个非常简单的电子政务系统,假如只有一部分:信访室和检查室。  
      我们的用户只有四类:信访室主任、信访室办信人、检查室主任、检查室办案人。    
       
      首先,我们来看一下它的权限分配(假设我是局长我修改了规则):  
      办信人A处理信访件xf001,那另一个办信人B就不能对xf001进行操作包括看都不行。但是信访室主任C可以看任何信访件,但是不能修改。xf001交到检查室,由D承办,他也可以看xf001的内容但不能修改,检查室主任E看不到任何xf001的内容,但E可以看xf001中的由D新增加的内容。    
       
      是不是有点复杂了?:)那么我们上面分析的模型是不是能拿来用呢?想想,有点问题。    
       
      本例中,信访室和检查室是两个相对独立的集合,所以我们先分开来考虑:  
      在信访室内部,对于xf001,A有操作权,C有观看权,B没有权限。对应表的role_xf_table如下:    
       
      UID   RID   BID    
      A   oper   xf001    
      B   oper   xf002    
       
      于是我们这样分配他们的权限:    
       
      select   RID   from   role_xf_table   where   (BID=current.xfNo   or   RID=leader)   and   UID=my.name;   my.RID=selected   RID;    
      if(   my.RID==oper)   permit   operate.    
      if(   my.RID==leader)   permit   view.    
       
      单纯的信访室内部,这样似乎没问题了,但是上面的权限分配中提到xf001交到检查室后,由D承办,他也可以看xf001的内容。于是上面的模型肯定要修改。    
       
      在这里,我们需要再引入一个“组”的概念。  
       
       
      信访室是一个组,在这个组内,我们可以用上面分析的模型对它的权限管理进行控制,同样,检查室也是一个组,组内的权限管理也可以套用我们上面的模型。但是组与组之间的权限管理呢?  
       
      D属于检查组,他却对信访室组中的xf001的内容有观看权,我们要修改上面的表,加入组GID,如下表role_group_table:  
       
      UID   RID   GID   BID    
      A   oper   xf   xf001    
      B   oper   xf   xf002    
      C   leader   xf        
      D   oper   jc   aj001=xf001    
      E   leader   jc        
       
      *   aj001是另一个操作对象,它与xf001之间有关联。也正是有这个关联,我们允许操作aj001的D有权限看xf001的内容。为了简化分析,我们把aj001等同于xf001。    
       
      我们的语句是:    
       
      select   RID,GID   from   role_group_table   where   (BID=current.blockID   or   RID=leader)   and   UID=my.name;  
      f(   oper   of   xf   )   permit   operate.    
      if(   oper   of   jc   )   permit   view.    
      if(   leader   of   xf   )   permit   view.    
       
      是不是有那么点道理?好,我们还可以对这个再做一下优化,比如这三个条件判断,不一定要写死在程序中,我们应该为它建立一个“RID与GID权限组合分配表”,字段为:RID、GID、Authority。    
       
      其实,在这里的RID也是另一个组的概念:oper组与leader组。我们可以为leader赋于一个共同的权限(比如收某种级别的公文等)。    
       
      其实这个模型还有很多要进一步讨论的地方,不过它大体上解决了问题,我们先放一放,再来看另一个模型吧。    
       
      第三个例子是:一个广告管理系统。用户可以分为三种:系统管理员、广告管理员和广告主用户。    
       
      系统管理员负责广告管理员的新增和删除。广告管理员只负责定向与数个广告主联系,并为他们提供广告业务。而广告主是我们的客户,每个广告主可能有几个广告。广告管理员只能看、修改自己负责的广告主的资料和此广告主交付的广告的资料。而广告主也只能看自己的广告的统计资料。    
       
      这里的权限比较简单,我们注意到这样的语汇:只能……自己……。所以这里的权限是一棵树。    
       
      如果我们继续沿用上面的分析,并且在这里也试着引入组的概念,如果每个广告管理员算为一个组,那么这个组里又可以分为每个广告主的一个小组?是不是这样?所以,这里的组有一种嵌套的关系,这也正是树的结构。如果不把它叫做组,这里的权限其实就是具有分级分支的关系。    
       
      我们再回过头来看一下上面的例子,在第二个例子中,组似乎有交叉的关系?如果RID与GID都被称为组,那它们之间的确是交叉的。   再看第一个例子,比较发现,如果把广告系统看成一个论坛,广告主相当于帖主,广告管理员就是板主,那么,唯一的区别在于每个帖主只能在自己特定的版区活动,java的兄弟不能去C++玩,这样看来,其实广告系统的权限才是最简单的。    
       
      与论坛系统对照而言,广告主也可以看作是广告管理员的一个子集,但是不是为他增加了某些权限,相反是削减了某些权限。    
       
      好象是这么一回事。这样一来,我们也可以用论坛使用的那一套数据表结构来描述它了。把BID改为PID,分别用role_table记录广告主与广告管理员的权限和ad_table记录广告与广告主的关系:    
       
       
      UID   RID   PID    
      a   oper   a    
      b   oper   b    
      c   adver   a    
      d   adver   a    
      e   adver   b    
        ID   OWN    
      1   c    
      2   c    
      3   d    
      4   e    
      5   e    
      6   e    
         
       
      语句这样:    
       
      select   role.PID   from   role_table,ad_table   where   role_table.UID=ad_table.OWN   and   ad_table.ID=current.ID;    
      if(   selected   role.PID   is   my.name   )   permit   operate.    
      else   forbid.    
       
      是不是表述了这个关系?   好吧,先到这里。    
       
      我要声明一点的是:这不是什么指南,也不是想告诉你如何如何做。只是我对这个问题的一些思考,我尽可能地把我纷繁的头绪整理出来,但是还是很乱,而且考虑得也很片面和肤浅,之所以拿出来,只是为了抛砖引玉,能引出您的真知灼见。    
       
      所以,我期待着你的参与,就上面的例子,或是你实际工作中的例子,给我们讲述一下你的思路。    
  • 相关阅读:
    ASP.NET登录记住用户名
    .NET枚举类型转为List类型
    display:inline-block 去除间隙
    sublime text 3 常用快捷键 、常用插件
    使用背景图代码
    Photo Shop 修改、维护
    前端协作流程
    Photo Shop切图
    Photo Shop 设置
    Flex 弹性布局
  • 原文地址:https://www.cnblogs.com/cxd4321/p/1407198.html
Copyright © 2011-2022 走看看