权限控制的设计一直是系统开发和框架结构中经常讨论的问题,如何设计一个简单而又行之有效却又可以提供高精度的权限控制粒度是我们一直探讨的问题。最近在翻看Joomla中的ACL部分发现了这个框架phpGACL
http://phpgacl.sourceforge.net/
运行他首先必须要有一个关系型数据库来存储权限控制数据,phpGACL是通过ADODB库来连接数据库的所以他可以方便的连接mysql,postgresql,oracle等等。在Joomla中的ACL系统是经过一些轻量级的改装后的,主要是在数据库层joomla放弃使用ADODB而采用了joomla中的数据库抽象类来存储数据库
理解权限控制
最好的解释权限控制的方法就是使用一些具体的实例而不是讲述枯燥的概念。Han是Millennium Falcon号飞船的船长,Chewie是他的二副,飞船上同时搭载着一些乘客包括:Luke, Obi-wan, R2D2 ,C3PO.Han需要对飞船上的每一个舱室定义一个访问权限包括:驾驶舱,动力舱,休息舱以及武器舱。
船长Han说”我和Chewie有权进入所有地方,但经过了一次非比寻常的超光速推进器修复之后我禁止Chewie再靠近动力舱,而乘客全部被限制在休息舱内”。从现在开始我们讨论的权限体系实际上是一个布尔数学体系,对于飞船上的每个人进入各个舱室的权限仅包括允许与拒绝,不存在任何第三种情况。
我们现在将上述情况描述为一个权限矩阵,他对应描述了谁有权进入哪里这个问题。具体如下图描述(0代表允许,X代表拒绝)。
列代表船长Han需要设定权限控制的舱室,而行则代表需要访问舱室的人员。抽象点说“舱室”就是需要控制权限的事物,这里我们称为”权限控制对象”Access Control Objects(ACO);“人员”就是需要权限去访问的事物,这里我们称为”权限需求对象”Access Request Objects(ARO)。人员需要权限进入舱室在我们的术语里就是AROs需要权限去访问ACOs。这里还有第三类对象称为附件权限对象Access eXtention Object (AXO),这个将在后面讨论,他共享一些属性并共同组成权限对象。
使用权限矩阵来管理权限是比较简单的,但也存在一些缺点。
1、他可以做到精细如果需要的话可以提供对每个人的管理
2、权限变的一目了然,谁有权进入那里,只要我们找到人员与舱室的交叉点也就找到了答案。
3、他很难去管理大型的权限体系,6个乘客4个舱室是一个非常小的权限体系,但如果有上千位乘客以及数百个舱室,应用矩阵来管理将何等麻烦,需要大量的精确而冗长的判断。权限矩阵很难适合这样的体系管理
4、统计上的麻烦,上面那个图如果统计谁可以进入动力舱是比较清楚的,但如果图变成下面这个样子估计就比较麻烦了
使用phpGACL来定义权限
对于大型权限系统的权限管理来说权限矩阵是很不合适的,这样我们就需要去寻找一个更合适的系统来完成这项工作,继承矩阵的优点同时也要舍去他的缺点。phpGACL就是一个非常好的解决方案。
phpGACL并非自底而上的描述权限相反他采用了一个自顶而下的顺序来描述权限,他是一个富有弹性的系统,允许用户使用大量的组来管理权限,很容易知道谁有权限去哪里。在phpGACL里使用一个ARO树来定义组和ARO对象。他与文件夹、文件的树型关系一样。这里组就象文件夹,而ARO对象就是文件。
现在给Han的飞船上的乘客也就是ARO设计一个ARO树,首先为飞船上的人员设计一个分类,这里Han 和Chewie是开船的,而剩下的人都是乘客
MillenniumFalconPassengersGroup
C─rew Group
│─Han ARO
│─Chewie ARO
─Passengers Group
─Obi-wan ARO
─Luke ARO
─R2D2 ARO
─C3PO ARO
这个树其实并不关联任何的权限只是对ARO对象做一个分类。我们应用权限实际是只是将ACO对象也就是舱室指派给ARO树上的Group或者ARO对象。Han说“默认情况下任何人不允许进入任何房间,但是船员可以进入任何舱室,乘客只允许进入休息舱”
MillenniumFalconPassengers
─Crew [ALLOW:ALL]
│─Han
Chewie│─
P─assengers [ALLOW:Lounge]
─Obi-wan
─Luke
─R2D2
─C3PO
现在我们自上而下解释这棵树,首先默认的权限永远是拒绝,所以所有人包括船员初始情况是拒绝进入任何舱室,但Han又说“船员可以进入任何舱室”,这个就发生了权限覆盖默认的权限被允许覆盖了,所以最终船员有权进入任何舱室,而乘客只允许进入休息舱。这种方式来描述权限比矩阵更加清楚,你可以清楚的明白谁可以去哪里,并且为什么他具备这样的权限也可以知道(Han和Chewie可以去飞船上的任意地方,因为他们同属于一个船员的组)
总结一下
Access Control Objects (ACOs) 权限控制对象,就是那些我们需要控制访问的对象,比如网页、数据库或者舱室。
Access Request Objects (AROs)权限需求对象,就是那些需要权限去访问的对象,比如人或者远程计算机。
ARO 树定义了ARO对象与GROUP的层次结构。组可以包含ARO对象也可以包含其他组 。
在ARO树上默认情况永远是拒绝访问
权限分配原则,使用一定的方法遍历整个ARO树,为每一个出现的ACO对象分配特定的权限给ARO或者GROUP
本文简单讲述了phpGACL的权限控制原理和基本概念,对于深入的GACL控制原理可以参考phpGACL手册。