载自:zendframework中文手册
简介
Zend_Acl 提供轻量并灵活的访问控制列表 (ACL,access control list) 功能和权限管理。一般地,应用软件可以利用这样的功能限制某些特定对象来访问特定保护的对象。
在本文档中,
Resource (资源)是一个限制访问的对象。
Role (角色)是一个可以发出请求去访问Resource的对象。
简单地说就是:Roles 请求访问 Resources。例如,如果一个人要用汽车,这样,这个人就是发出请求的 Role,而这辆汽车就是 Resource,所以使用这辆车就在控制之中了。
通过规范和访问控制列表(ACL)的使用,应用软件可以控制如何授权给发出请求的对象(Roles)来访问被保护的对象(Resources)。
2.1.1. 关于资源(Resource)
在 Zend_Acl 中,创建建一个 Resource 非常简单。Zend_Acl 提供了Zend_Acl_Resource_Interface 使开发者创建 Resources 非常容易。为了使Zend_Acl把某个对象当作一个Resource,一个类只需要实现这个只包含了一个方法 getResourceId() 的接口。 另外,Zend_Acl_Resource是一个包含在 Zend_Acl 里作为一个基本的 Resource 实现的类,开发者可以任意扩展它。
Zend_Acl 提供了一个树结构,它可以添加多个 Resources (或者叫“访问控制下的区域”)。因为 Resources 被存储在这样一个树结构,所以它们可以被组织成从一般(树根)到特殊(树叶)。基于特殊Resource的查询将自动从Resource的等级结构中搜索分配给祖先Resources的规则,它允许简单的规则继承。例如,要把一个缺省的规则应用到一个城市的每个建筑物,就简单地把这个规则分配给这个城市,而不是把规则分配给每个建筑物。然而,有些建筑物也许要求例外的规则,在Zend_Acl里,很容易地通过分配例外规则给每个有这样要求的建筑物来实现。一个 Resource 可以从唯一的一个父 Resource 继承,而这个父 Resource 也有它自己的父 Resource,等等。
Zend_Acl 也支持基于 Resources 的权限(例如:"create", "read", "update", "delete"), 开发者可以根据 Resource 分配影响全部或者特殊权限的规则。
2.1.2. 关于角色(Role)
象 Resources 一样,创建一个 Role 也非常简单。 Zend_Acl 提供了 Zend_Acl_Role_Interface 使开发者创建 Roles 非常容易。为了使Zend_Acl把某个对象当作一个 Role,一个类只需要实现这个只包含了一个方法 getRoleId() 的接口。 另外,Zend_Acl_Role是一个包含在Zend_Acl里作为一个基本的 Role 实现的类,开发者可以任意扩展它。
在 Zend_Acl, 一个 Role 可以从一个或多个 Role 继承,这就是在 Role 中支持规则的继承。例如,一个用户 Role,如 “sally”,可以属于一个或多个 Role,如:“editor”和“administrator”。开发者可以分别给“editor”和“administrator”分配规则,而 “sally”将从它们俩继承规则,不需要直接给“sally”分配规则。
虽然从多重角色继承的能力非常有用,但是多重继承也带来了一定程度的复杂性。下面的例子来示例含糊情形和Zend_Acl如何解决它。
测试代码:
<?php
/**
* Zend_Acl测试代码
* @created:2007-10-22
*/
class AclController extends Zend_Controller_Action {
public function init(){
$this->_helper->viewRenderer->setNoRender();
require_once 'Zend/Acl.php';
}
public function indexAction(){
$acl = new Zend_Acl();
require_once 'Zend/Acl/Role.php';
$acl->addRole(new Zend_Acl_Role('guest'))
->addRole(new Zend_Acl_Role('member'))
->addRole(new Zend_Acl_Role('admin'));
$parents = array('guest', 'member', 'admin');
$acl->addRole(new Zend_Acl_Role('someUser'), $parents);
require_once 'Zend/Acl/Resource.php';
$acl->add(new Zend_Acl_Resource('someResource'));
$acl->deny('guest', 'someResource');
$acl->allow('member', 'someResource');
echo $acl->isAllowed('someUser', 'someResource') ? 'allowed' : 'denied';
}
/**
* 2.1.4. 注册角色(Role)
* @date 2007-10-22
*/
public function test2Action(){
$acl = new Zend_Acl();
// 用 Zend_Acl_Role 把组添加到 Role 注册表
require_once 'Zend/Acl/Role.php';
// Guest 不继承访问控制
$roleGuest = new Zend_Acl_Role('guest');
$acl->addRole($roleGuest);
// Staff 从 guest 继承
$acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
/* 另外, 上面的也可这样来写:
$roleGuest = $acl->addRole(new Zend_Acl_Role('staff'), 'guest');
//*/
// Editor 从 staff 继承
$acl->addRole(new Zend_Acl_Role('editor'), 'staff');
// Administrator 不继承访问控制
$acl->addRole(new Zend_Acl_Role('administrator'));
}
/**
* 定义访问控制
* @date 2007-10-22
* @author hqlong
*/
public function test3Action(){
$acl = new Zend_Acl();
require_once 'Zend/Acl/Role.php';
$roleGuest = new Zend_Acl_Role('guest');
$acl->addRole($roleGuest);
$acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
$acl->addRole(new Zend_Acl_Role('editor'), 'staff');
$acl->addRole(new Zend_Acl_Role('administrator'));
// Guest 只可以浏览内容
$acl->allow($roleGuest, null, 'view');
/* 另外, 上面也可写为:
$acl->allow('guest', null, 'view');
//*/
// Staff 从 guest 继承浏览权限,但也要另外的权限
$acl->allow('staff', null, array('edit', 'submit', 'revise'));
// Editor 从 Staff 继承 view, edit, submit 和 revise 权限
// 但也要另外的权限
$acl->allow('editor', null, array('publish', 'archive', 'delete'));
// Administrator 不需要继承任何权限,它拥有所有的权限
$acl->allow('administrator');
}
/**
* 查询 ACL
*
*/
public function test4Action(){
$acl = new Zend_Acl();
require_once 'Zend/Acl/Role.php';
$roleGuest = new Zend_Acl_Role('guest');
$acl->addRole($roleGuest);
$acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
$acl->addRole(new Zend_Acl_Role('editor'), 'staff');
$acl->addRole(new Zend_Acl_Role('administrator'));
// Guest 只可以浏览内容
$acl->allow($roleGuest, null, 'view');
/* 另外, 上面也可写为:
$acl->allow('guest', null, 'view');
//*/
// Staff 从 guest 继承浏览权限,但也要另外的权限
$acl->allow('staff', null, array('edit', 'submit', 'revise'));
// Editor 从 Staff 继承 view, edit, submit 和 revise 权限
// 但也要另外的权限
$acl->allow('editor', null, array('publish', 'archive', 'delete'));
// Administrator 不需要继承任何权限,它拥有所有的权限
$acl->allow('administrator');
echo $acl->isAllowed('guest', null, 'view') ? "allowed" : "denied"; // 允许
echo $acl->isAllowed('staff', null, 'publish') ?"allowed" : "denied"; // 禁止
echo $acl->isAllowed('staff', null, 'revise') ?
"allowed" : "denied"; // 允许
echo $acl->isAllowed('editor', null, 'view') ?
"allowed" : "denied"; // 允许,因为从 guest 继承而来
echo $acl->isAllowed('editor', null, 'update') ?
"allowed" : "denied"; // 禁止,因为对于 'update' 没有 allow 规则
echo $acl->isAllowed('administrator', null, 'view') ?
"allowed" : "denied"; // 允许,因为 administrator 有所有权限
echo $acl->isAllowed('administrator') ?
"allowed" : "denied"; // 允许,因为 administrator 有所有权限
echo $acl->isAllowed('administrator', null, 'update') ?
"allowed" : "denied"; // 允许,因为 administrator 有所有权限echo $acl->isAllowed('guest', null, 'view') ?
echo $acl->isAllowed('staff', null, 'publish') ?
"allowed" : "denied"; // 禁止
echo $acl->isAllowed('staff', null, 'revise') ?
"allowed" : "denied"; // 允许
echo $acl->isAllowed('editor', null, 'view') ?
"allowed" : "denied"; // 允许,因为从 guest 继承而来
echo $acl->isAllowed('editor', null, 'update') ?
"allowed" : "denied"; // 禁止,因为对于 'update' 没有 allow 规则
echo $acl->isAllowed('administrator', null, 'view') ?
"allowed" : "denied"; // 允许,因为 administrator 有所有权限
echo $acl->isAllowed('administrator') ?
"allowed" : "denied"; // 允许,因为 administrator 有所有权限
echo $acl->isAllowed('administrator', null, 'update') ?
"allowed" : "denied"; // 允许,因为 administrator 有所有权限
}
public function test5Action(){
$acl = new Zend_Acl();
require_once 'Zend/Acl/Role.php';
$roleGuest = new Zend_Acl_Role('guest');
$acl->addRole($roleGuest);
$acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
$acl->addRole(new Zend_Acl_Role('editor'), 'staff');
$acl->addRole(new Zend_Acl_Role('administrator'));
// Guest 只可以浏览内容
$acl->allow($roleGuest, null, 'view');
/* 另外, 上面也可写为:
$acl->allow('guest', null, 'view');
//*/
// Staff 从 guest 继承浏览权限,但也要另外的权限
$acl->allow('staff', null, array('edit', 'submit', 'revise'));
// Editor 从 Staff 继承 view, edit, submit 和 revise 权限
// 但也要另外的权限
$acl->allow('editor', null, array('publish', 'archive', 'delete'));
// Administrator 不需要继承任何权限,它拥有所有的权限
$acl->allow('administrator');
// 新 marketing 组从 staff 组继承许可
$acl->addRole(new Zend_Acl_Role('marketing'), 'staff');
require_once 'Zend/Acl/Resource.php';
$acl->add(new Zend_Acl_Resource('newsletter')); // newsletter
$acl->add(new Zend_Acl_Resource('news')); // news
$acl->add(new Zend_Acl_Resource('latest'), 'news'); // latest news
$acl->add(new Zend_Acl_Resource('announcement'), 'news'); // announcement news
// Marketing must be able to publish and archive newsletters and the latest news
$acl->allow('marketing', array('newsletter', 'latest'), array('publish', 'archive'));
// Staff (和 marketing, 通过继承), 禁止修订 latest news
$acl->deny('staff', 'latest', 'revise');
// Everyone (包括 administrators) 禁止归档 news announcements
$acl->deny(null, 'announcement', 'archive');
echo $acl->isAllowed('staff', 'newsletter', 'publish') ?
"allowed" : "denied"; // denied
echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
"allowed" : "denied"; // allowed
echo $acl->isAllowed('staff', 'latest', 'publish') ?
"allowed" : "denied"; // denied
echo $acl->isAllowed('marketing', 'latest', 'publish') ?
"allowed" : "denied"; // allowed
echo $acl->isAllowed('marketing', 'latest', 'archive') ?
"allowed" : "denied"; // allowed
echo $acl->isAllowed('marketing', 'latest', 'revise') ?
"allowed" : "denied"; // denied
echo $acl->isAllowed('editor', 'announcement', 'archive') ?
"allowed" : "denied"; // denied
echo $acl->isAllowed('administrator', 'announcement', 'archive') ?
"allowed" : "denied"; // denied
// 除去 “禁止 staff 修订最近的新闻”(和marketing, 由于继承的原因) (等于允许staff修订最近的新闻 Jason注)
$acl->removeDeny('staff', 'latest', 'revise');
echo $acl->isAllowed('marketing', 'latest', 'revise') ?
"allowed" : "denied"; // allowed
// 除去 marketing 发布和归档 newsletters 的许可
$acl->removeAllow('marketing', 'newsletter', array('publish', 'archive'));
echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
"allowed" : "denied"; // denied
echo $acl->isAllowed('marketing', 'newsletter', 'archive') ?
"allowed" : "denied"; // denied
// 允许 marketing 对 latest news 有所有的许可
$acl->allow('marketing', 'latest');
echo $acl->isAllowed('marketing', 'latest', 'publish') ?
"allowed" : "denied"; // allowed
echo $acl->isAllowed('marketing', 'latest', 'archive') ?
"allowed" : "denied"; // allowed
echo $acl->isAllowed('marketing', 'latest', 'anything') ?
"allowed" : "denied"; // allowed
}
}
?>
机器人 2007-10-22 于 北京