CakePHP中文手册【翻译】-ACL
访问控制列表(ACL)
第1节
理解ACL如何工作
最重要,也最强大的事情是需要一系列的访问控制。访问控制列表是一种细粒度,易维护以及易管理的方式来管理应用程序权限。访问控制列表或ACL[1]处理2件主要的事情:他们想要的事情,以及想要他们的事情。按照ACL的行话来说,事情想要的使用的原料(最常见的是用户)称为访问请求对象,或者ARO(Access Request Object)。这些实体之所以称为'对象',是因为有的时候请求的对象不是一个人-有的时候你可能想限制访问某个Cake Controller,而此Controller在应用程序的其它部分不得不初始化逻辑。ACO可以是你想控制的任何东西,从一个Controller动作,到一个Web Service,或到一个你祖母的在线日记上去。
为了即刻使用所有的缩写形式,可以如下:ACL是用来决定一个ARO什么时候可以访问一个ACO。
现在,为了帮助你理解它,让我们使用一个实际的例子吧。假想一下,再过一会,一个冒险家们使用的计算机系统。这组冒险家的老大在为其他人员维护一个正常程度的隐私和安全时,他又想继续处理他们的请求。其中涉及到的ARO如下:
Gandalf
Aragorn
Bilbo
Frodo
Gollum
Legolas
Gimli
Pippin
Merry
|
这些就是系统里的实体,他们会请求系统的东西(ACO)。你应该注意到ACL并“不是”一个系统,它的意思是指认证的用户。你也应该有一种方式来存储用户信息,而且当用户进入系统时,能够验证他们的身份。一旦你知道用户是谁时,这就是ACL真正发光之处!OK,还是让我们回到冒险家那里吧。
Gandalf需要做的下一件事情是制作一个系统会处理的东西(或ACO)的初始化列表.他的列表可能如下:
武器(Weapon)
环(Ring)
咸肉(Salted Pork)
外交策略(Diplomacy)
啤酒(Ale) |
传统上,我们会使用一组矩阵来管理系统,此矩阵展示了一组用户和与之相关对象的权限。如果此信息存储在一个表里,它可能会像下面这样,其中X表示拒绝访问,O代表允许访问:
武器 环 咸肉 外交策略 啤酒 Gandalf X X O O O
Aragorn O X O O O
Bilbo X X X X O
Frodo X O X X O
Gollum X X O X X
Legolas O X O O O
Gimli O X O X X
Pippin X X X O O
Merry X X X X O
|
让我们看第一眼,看起来这组系统工作得非常出色。这里的分配可以保护安全(只有Frodo可以使用环),并且可以保护突发事件(让Hobbit得不到咸肉)[2]。他们读起来看似已经足够细致,足够容易,真的吗?
对于像这样的一个小型系统,也许一个矩阵就可以完成。但是对于一个逐步增长的系统或者一个带有大数量的资源(ACO)和用户(ARO)的系统来说,一个表格可能变得笨重,而不是变得快捷。例如,假设我们打算想控制对几百个战争驻扎地的访问,以及试图按单元管理他们。矩阵的另外一个缺点是你不会真正的按逻辑将这些用户分组,或者对已按逻辑分组的用户做出一连串的权限变化。例如,一旦战争结束,它肯定会很好的自动允许Hobbit访问啤酒和猪肉:当对所有‘Hobbit'做出一连串权限改变很容易时,实现一个基于独立用户的基本原则则是令人乏味的,也是有错误倾向的。
以树结构实现ACL是最常见的。通常有一个ARO树和ACO树。通过将他们以树结构组织,权限仍然可以以细粒度来处理,但也可以很好的保持对大蓝图的把握。作为一个英明的老大,在他的新系统里,Gandalf选择使用ACL,并将他的对象像下面一样进行组织:
环的团体关系:
战士
Aragorn
Legolas
Gimli
指挥家
Gandalf
Hobbit
Frodo
Bilbo
Merry
Pippin
访问者
Gollum
|
按这种方式建立我们团体,我们可以定义树的访问控制,并将这些权限应用到任何子节点中。缺省的权限是拒绝访问任何东西。与你处理树的方式一样,挑选一些权限并使用他们,最后应用的权限(将它应用到你正想知道的ACO上)就是你保持的那一个,因此,使用我们的ARO树,Gandalf可以出挂起一些权限:
环的团体关系: [Deny: ALL]
战士 [Allow: Weapons, Ale, Elven Rations, Salted Pork] Aragorn
Legolas
Gimli
指挥家 [Allow: Salted Pork, Diplomacy, Ale] Gandalf
Hobbit [Allow: Ale]
Frodo
Bilbo
Merry
Pippin
访问者 [Allow: Salted Pork] Gollum
|
如果你想使用ACL查看是否允许Pippin访问啤酒,我们先得获取他在树上的路径,即Fellowship->Hobbits->Pippin.然后我们得看看依附在这些节点上的不同权限,并使用与Pinppin和啤酒相关的最具体的权限。
1.
Fellowship
= DENY Ale,拒绝(因为它被设置为拒绝所有ACO)
2.
Hobbits =
ALLOW Ale, 允许
3.
Pippin = ?;确实不存在任何指定的啤酒信息,因此我们可以为ALLOW。
4.
最后结果:
允许啤酒.
树也允许我们对更细粒度的控制做出更好的调整,但同时仍然可以保持对ARO组做出交替的变化:
Fellowship of the Ring: [Deny: ALL]
Warriors [Allow: Weapons, Ale, Elven Rations, Salted Pork]
Aragorn [Allow: Diplomacy]
Legolas
Gimli
Wizards [Allow: Salted Pork, Diplomacy, Ale]
Gandalf
Hobbits [Allow: Ale]
Frodo [Allow: Ring]
Bilbo
Merry [Deny: Ale]
Pippin [Allow: Diplomacy]
Vistors [Allow: Salted Pork]
Gollum
|
你从中可以看到它,是因为Aragorn ARO的维护与于其他战士ARO组类似,但是当你看到合适时,你仍然可以做出好节奏的调整以及特殊的情况。同样,权限确实为DENY,仅向下遍历树的变化强制为一个ALLOW。为了看看Merry是否可以访问啤酒(Ale),我们需要查找他在树上的路径:Fellowship->Hobbits->Merry,并沿此路径向下工作,同时追踪与ale相关的权限:
1. Fellowship = DENY (因为它设置为拒绝所有), 因此拒绝ale
2. Hobbits = ALLOW: ale,允许ale。
3. Merry = DENY ale,因此拒绝ale
4. 最终结果: 拒绝ale。
第 2节
定义权限:基于INI的Cake
ACL
Cake的第一个ACK实现是基于INI文件,此文件存储在Cake安装目录下面。由于它的实用性以及稳定性,我们建议你使用数据库存储ACL的解决方案,因为它具有可以在空中创建新ACO和ARO的能力。在简单的应用程序中,因为它的用途我们推荐它-并且特别是对那些因为某些原因而没有使用数据库的家伙们。
ARO/ACO权限在/app/config/acl.ini.php中指定。指定访问权限的指令可以在acl.ini.php文件的开头找到:
; acl.ini.php - Cake ACL Configuration
; ---------------------------------------------------------------------
; Use this file to specify user permissions.
; aco = access control object (something in your application)
; aro = access request object (something requesting access)
;
; User records are added as follows:
;
; [uid]
; groups = group1, group2, group3
; allow = aco1, aco2, aco3
; deny = aco4, aco5, aco6
;
; Group records are added in a similar manner:
;
; [gid]
; allow = aco1, aco2, aco3
; deny = aco4, aco5, aco6
;
; The allow, deny, and groups sections are all optional.
; NOTE: groups names *cannot* ever be the same as usernames!
|
通过使用INI文件,你也应指定用户(ARO),他们属于的组,以及他们自己拥有的权限。你也指定带有权限的组。为了学习如何利用INI文件使用Cake的ACL组件来检验权限,参看11.4这节。
第3节
定义权限: Cake的数据库ACL
开始
ACL权限的实现缺省的是数据库存储。数据库ACL,或者dbACL,由一组核心的model,以及一个命令行脚本组成,此命令行脚本在Cake安装时而产生。Cake使用model与你的数据库进行交互,这样做的目的是为了存储和获取ACL树上的节点。使用命令行脚本有助于你开始与你的树进行交互。
为了开始,首先需要保证/app/config/database.php存在,并且正确的配置它。对于一个Cake的新安装,告诉它这些最简单的方法就是使用一个web浏览器来完成安装。如果你正确安装,在离页面顶端之处,你应该可以看到信息"Your database configuration file is present." 以及 "Cake is able to connect to the database."参看4.1节获取更多关于数据库配置的的信息。
下一步,使用ACL命令行脚本初始化你的数据库来存储ACL信息。/cake/scripts/acl.php 的脚本帮助你完成它。执行下面的命令(来自/cake/scripts/目录)为ACL初始化你的数据库。
使用acl.php初始化数据库
$ php acl.php initdb |
在这里,你应该可以检查你项目的数据库是否有新表。如果你正奇怪Cake如何将树的信息存储在这些表里,研读一下修改的数据库树遍历。基本上,它存储了节点,以及他们在树中的位置。
和aros数据库表存储了他们各自树的节点信息,aros_acos表用来将ARO链接到他们可以访问的ACO。
现在,你应该可以创建ARO和ACO树了。
创建ARO和ACO
引用ARO/ACO有2种方法,一种是给他们一个数字型的ID,它常常是他们属于的那个表的主键。另外一种方法是给他们一个字符串别名。这2种方法不会相互排斥。
定义Aro_Cake model可以创建一个新的ARO。Aro类的create()方法有3个参数:link_id, $parent_id,以及$alias。此方法创建一个在parent_id指定的父对象之下的ACL对象,或者是如果传入的$parent_id为null,作为一个根对象。$link_id允许你将当前用户对象链接到Cake的ACL结构。别名参数允许你放入一个非整型ID的对象。
在你能够创建ACO和ARO之前,我们需要加载这些类。实现加载的最简单方法是使用$components数组,并将Cake ACL组件包含在Controller里:
var $components = array('Acl'); |
一旦完成,我们看看这些对象的创建实例是什么样子。可以把下面的代码放在一个Controller的动作中:
$aro = new Aro(); |
你也可以利用使用了$acl.php的命令行脚本创建ARO,创建的ARO是<link_id>
<parent_id> <alias>.
以类似的方法创建ACO:
$aco = new Aco(); |
相应的命令行脚本命令可能是:$acl.php 创建ACO <link_id> <parent_id> <alias>.
分配权限
A在创建ACO和ARO后,最后我们可以分配2个组之间的权限。使用Cake的核心组件来完成。让我们继续我们的例子吧:
// First, in a controller, we'll need
access |
这个特殊的controller并不是特别有用,但是它会向你展示它们工作的过程。使用和你的用户管理controller相连的Acl组件会是一个最好的使用方法。系统一旦创建了一个用户,就会创建它的ARO,并将它放到树的正确位置,而且将权限分配到基于它的身份的特定的ACO或ACO组中去。
也可以使用与Cake一起打包的命令行脚本分配权限。此语法和model函数有些类似,而且可以通过执行$php acl.php帮助来查看它。
第4章
检验权限:ACL组件
检验权限是Cake ACL最简单的一部分:它包括使用一个Acl组件中的简单方法:check().在你的应用程序中实现ACL的一个优秀方法是将动作放在AppController里,此Controller会完成ACL检验。一旦把它放在那里,你就可以访问Acl组件,并完成应用程序级的权限检验。这里是实现的实例:
class AppController extends
Controller |
基本上,通过在AppController里使Acl组件可用,它将在应用程序中的任何Controller中都可见。
// Here's the basic
format: |
[1]因为ACL直观明了,在后面都将采用ACL,以后不再说明
[2] 译者注:Hobbit是英国作家J.R.R.Tolkien笔下创造的生性善良平和的穴居矮人。请访问www.tolkiensociety.org。