位运算实现ACL授权与认证过程的原理解析

来源:互联网 发布:淘宝五金冠店铺是哪家 编辑:程序博客网 时间:2024/03/29 12:33

        
ACL权限管理位运算

目录(?)[+]

  1. 先需要知道什么是授权与认证
    1. 关于授权比较详细的解释
    2. 关于认证比较详细的解释
  2. ACL在代码中的体现
  3. 位运算如何实现授权与认证
    1. 授权与取消授权部分
    2. 认证部分
    3. 设置本授权是否是继承的
  4. 位运算简介
  5. 总结

在任何权限管理系统中,ACL(Access Control List)都是非常重要且有不可或缺的。权限管理主要包括授权与认证两大部分,下面就看ACL是如何实现授权与认证的。


先需要知道什么是授权与认证


关于授权比较详细的解释:


1、授权,指将权限授予角色或用户

   a)如果用户A拥有角色B、角色C,那么,缺省的情况下,用户A将拥有被分配给角色B和角色C的所有权限(即默认情况下,用户A继承其拥有的角色所具有的所有权限);

   b)如果用户拥有多个角色,那么用户的权限是这些角色权限的合集;

   c)如果用户拥有多个角色,而且角色之间的授权有冲突(比如对同一个资源的同一个操作,一个角色为“允许”,另外一个角色为“不允许”),将以优先级别高的角色(所谓优先级别,也就是对于这个用户所拥有的角色而言,是有顺序的,同一个角色在不同的用户那里可能拥有不同的优先级);

   d)除了可以对角色进行授权外,也可以针对用户进行授权,也就是说,将权限授予用户。针对某个资源的所有操作,我们可以设置这些权限对用户来说是“继承”或“不继承”;

       i.继承:意思是这些权限将使用其(即用户)所拥有的角色的权限,而不使用其(即用户)单独设置的权限,

       ii.不继承:意思是这些权限将使用其单独设置的权限,而不使用其所拥有的角色的权限。


一言以蔽之:授权就是颁发许可证的过程。比如导游证,你有了导游证,你就可以上岗;如果没有,对不起,你玩去。授权就相当于与授予你导游证的过程。


注意需要的说明一点:什么是角色?这里有了用户,为什么还要有角色,用户与角色有什么不同?

角色是抽象的概念。角色可以理解为职位,比如系统管理员,部门经理等这些职位,而用户就是具体的人。一个用户可以身兼多职,一个职务也可以有多个人来负责。所以人员与角色是多对多的关系。


关于认证比较详细的解释:


2、认证,指用户访问资源的某些操作时,根据授权,判断是否允许用户的访问

   a)在用户访问的时候,需要进行即时的判断(是否有权访问)

   b)应该提供查询的功能,可以查询某个用户所拥有的所有权限


一言以蔽之:认证是一个检查过程。给你颁发的导游证,上岗前还需要对你进行检查,如果检查出来你没有导游证,对不起,你不能上岗。


ACL在代码中的体现


知道了什么是授权与认证,下面看授权与认证如何在代码中体现。下面是一个访问控制类ACL的实现。

[java] view plaincopyprint?
  1. package com.lzq.model;  
  2.   
  3. /** 
  4.  * ACL类   访问控制类 
  5.  */  
  6. public class ACL {  
  7.     /** 
  8.      * 授权允许:  不确定   不允许   允许 
  9.      */  
  10.     public static final int ACL_NEUTRAL = -1;  
  11.     public static final int ACL_NO = 0;  
  12.     public static final int ACL_YES = 1;   
  13.       
  14.     /** 
  15.      * 授权状态,用其后四位(bit)来表示CRUD操作 
  16.      */  
  17.     private int aclState;  
  18.       
  19.     /** 
  20.      * 表示是否继承,0表示不继承,1表示继承 
  21.      *  
  22.      */  
  23.     private int aclTriState;  
  24.   
  25.     public int getAclState() {  
  26.         return aclState;  
  27.     }  
  28.     public void setAclState(int aclState) {  
  29.         this.aclState = aclState;  
  30.     }  
  31.     public int getAclTriState() {  
  32.         return aclTriState;  
  33.     }  
  34.     public void setAclTriState(int aclTriState) {  
  35.         this.aclTriState = aclTriState;  
  36.     }  
  37.       
  38.     /** 
  39.      * acl实例跟主体和资源关联 
  40.      * 针对此实例进行授权,某种操作是否允许 
  41.      * @param permission 只可取0、1、2、3 
  42.      * @param yes true表示允许,false表示不允许 
  43.      */  
  44.     public void setPermission(int permission,boolean yes){  
  45.         int temp = 1;  
  46.         temp =temp <<permission;  
  47.         if (yes) {  
  48.             aclState |= temp;  
  49.         }else {  
  50.             aclState &= ~temp;  
  51.         }  
  52.     }  
  53.       
  54.     /** 
  55.      * 获得ACL授权 
  56.      * @param permission C/R/U/D授权 
  57.      * @return 授权标识,允许/不允许/不确定 
  58.      */  
  59.     public int getPermission(int permission){  
  60.           
  61.         //如果继承,则返回未定的授权信息  
  62.         if (aclTriState == 0xFFFFFFFF) {  
  63.             return ACL_NEUTRAL;  
  64.         }  
  65.           
  66.         int temp = 1;  
  67.         temp = temp << permission;  
  68.           
  69.         temp &=aclState;  
  70.           
  71.         if (temp !=0) {  
  72.             return ACL_YES;  
  73.         }  
  74.         return ACL_NO;  
  75.     }  
  76.       
  77.     /** 
  78.      * 设置本授权是否是继承的 
  79.      * @param yes true表示继承,false表示不继承 
  80.      */  
  81.     public void setExtends(boolean yes){  
  82.         //0xFFFFFFFF是-1的补码表示  
  83.         if (yes) {  
  84.             aclTriState =0xFFFFFFFF;  
  85.         }else {  
  86.             aclTriState = 0;  
  87.         }  
  88.     }  
  89.     public static void main(String[] args) {  
  90.         System.out.println(0xFFFFFFFF);  
  91.     }  
  92. }  


位运算如何实现授权与认证


假设从右向左, 分别代表CRUD。那么, 我们CRUD的代码就应该是0123(也就是移位时要移的位数), 因为我们要进行移位进行认证。


1、授权与取消授权部分:


拿D操作来举例说明:

一个int temp =1的临时变量,aclState为原始授权状态。temp的二进制代码表示是:00000000 00000000 00000000 00000001;

D对应的代码是3。根据temp = temp<<permission,将temp向左移3位。temp变为:00000000 00000000 00000000 00001000;

假设原始授权是aclState=00000000 00000000 00000000 00000101;

当变量yes=true时,为授权。将temp与aclState求|运算,因为temp现在只有他要授权的位为1,求或运算后,aclState=00000000 00000000 00000000 00001101。这样就授权成功。

当变量yes=false时,为取消授权。将temp取反为:~temp=11111111 11111111 11111111 11110111。然后与aclState原状态做与运算。运算后,aclState= 00000000 00000000 00000000 00000101,仍未原状态,授权取消。


一言以蔽之:授权的过程,就是经过位运算,将移动后的位(R移动1位,移动后对应的位为从右到左第二位;U移动2位,移动后对应的位为从右到左第三位)变为1;取消授权就是经过位运算后,原状态未发生变化。


代码实现如下:

[java] view plaincopyprint?
  1. /** 
  2.      * 针对此实例进行授权,某种操作是否允许 
  3.      * @param permission 只可取0、1、2、3 
  4.      * @param yes true表示允许,false表示不允许 
  5.      */  
  6.     public void setPermission(int permission,boolean yes){  
  7.         int temp = 1;  
  8.         temp =temp <<permission;  
  9.         if (yes) {  
  10.             aclState |= temp;  
  11.         }else {  
  12.             aclState &= ~temp;  
  13.         }  
  14.     }  



2、认证部分:


认证的过程与授权的过程可以认为是逆过程。

认证中仍然拿D操作来举例:首先看继承状态,如果继承状态aclTriState=-1 (0xFFFFFFFF为-1的补码表示)表明授权状态未确定;

一个int temp =1的临时变量,aclState为原始授权状态。temp的二进制表示为:00000000 00000000 00000000 00000001;

D对应的代码是3。根据temp = temp<<permission,将temp向左移3位。temp变为:00000000 00000000 00000000 00001000;

假设原始的授权状态aclState=aclState=00000000 00000000 00000000 00001101;

临时变量temp与aclState做与运算。temp=temp&aclState=00000000 00000000 00000000 00001000,这时temp不等于0,表示获取ACL授权。


一言以蔽之:认证实现就是授权的逆过程,将授权状态与移动后的temp做与运算,如果结果不等于0,表示获取ACL授权;如果结果等于零,表示不能获取授权(与授权过程相对应)。


代码实现如下:

[java] view plaincopyprint?
  1. /** 
  2.      * 获得ACL授权 
  3.      * @param permission C/R/U/D授权 
  4.      * @return 授权标识,允许/不允许/不确定 
  5.      */  
  6.     public int getPermission(int permission){  
  7.         //如果继承,则返回未定的授权信息  
  8.         if (aclTriState == 0xFFFFFFFF) {  
  9.             return ACL_NEUTRAL;  
  10.         }  
  11.         int temp = 1;  
  12.         temp = temp << permission;  
  13.         temp &=aclState;  
  14.         if (temp !=0) {  
  15.             return ACL_YES;  
  16.         }  
  17.         return ACL_NO;  
  18.     }  



3、设置本授权是否是继承的


权限不仅能够授予给角色,也能够直接授权给用户。直接授权给用户的时候,要进行是否继承判断。

继承意思是这些权限将使用用户所拥有的角色的权限,而不使用用户单独设置的权限;

不继承:意思是这些权限将使用其单独设置的权限,而不使用其所拥有的角色的权限。

如果yes为true,那么aclTriState=-1,表示本授权是继承的;如果yes为false,那么aclTriState=0,表示本授权是不继承的。

代码实现如下:


[java] view plaincopyprint?
  1. /** 
  2.      * 设置本授权是否是继承的 
  3.      * @param yes true表示继承,false表示不继承 
  4.      */  
  5.     public void setExtends(boolean yes){  
  6.         //0xFFFFFFFF是-1的补码表示  
  7.         if (yes) {  
  8.             aclTriState =0xFFFFFFFF;  
  9.         }else {  
  10.             aclTriState = 0;  
  11.         }  
  12.     }  

位运算简介


基本的位操作符有与、或、异或、取反、左移、右移这6种,它们的运算规则如下所示:

 

符号

 描述

 运算规则        

&      

 

两个位都为1时,结果才为1

|  

     

两个位都为0时,结果才为0

^    

异或

两个位相同为0,相异为1

~   

取反

0110

<< 

左移

各二进位全部左移若干位,高位丢弃,低位补0

>> 

右移

各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)

注意以下几点:

1.在这6种操作符,只有~取反是单目操作符,其它5种都是双目操作符。

2.位操作只能用于整形数据,对float和double类型进行位操作会被编译器报错。


总结


本文主要介绍了授权与认证的概念,位运算基础的简单介绍,如何通过位运算进行授权与认证。大家可以对照最后给出的位运算表格,对授权和认证过程进行比对,看它们具体是如何实现的。

其实一条acl授权记录中除了aclState和aclTriState之外,还主要记录了:角色、资源和授权三条信息。具体内容在后文介绍。

0 0
原创粉丝点击