Programmer's Reference Guide

简介

精细的访问控制

精细的访问控制

前一章节中定义的基本的 ACL 显示如何在整个 ACL (所有的 resources )允许各种各样的权限。然而在实践中,访问控制趋向于拥有例外和可变程度的复杂性。Zend_Acl 允许你直截了当并灵活地完成这些精细准确的控制。

对于CMS范例,'staff' 组覆盖了绝大多数用户的需求,同时,一个新的 'marketing' 组要求在CMS中访问时事通讯和最近的新闻。这个组相当地自给自足并有能力发布和归档时事通讯和最近的新闻。

另外,还要求 'staff' 组被允许浏览新闻故事但不能修订最近的新闻。最后,不可能让每一个人(包括系统管理员)去归档任何'announcement' 新闻故事,因为它们只有1-2天的生命周期。

首先我们修订 role 注册表来反映这些变化。我们已经确定 'marketing' 组和 'staff' 组有着同样的基本许可,所以我们用从 'staff' 组继承许可的方法来定义 'marketing' 组

// 新 marketing 组从 staff 组继承许可
$acl->addRole(new Zend_Acl_Role('marketing'), 'staff');

        

然后, 注意上面的访问控制涉及到特定的 resources ( 例如 "newsletter", "latest news", "announcement news"). 现在我们来添加这些 resources:

// Create Resources for the rules

// newsletter
$acl->add(new Zend_Acl_Resource('newsletter'));

// news
$acl->add(new Zend_Acl_Resource('news'));

// latest news
$acl->add(new Zend_Acl_Resource('latest'), 'news');

// announcement news
$acl->add(new Zend_Acl_Resource('announcement'), 'news');

        

接着,这个是在 ACL 的目标区域定义更特定的规则的概况:

// 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');

        

我们现在能够查询到 ACL 的最新变化:

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

        

除去访问控制

要从 ACL 中除去一个或多个访问规则,只要简单地用 removeAllow()removeDeny() 方法即可。如果提供一个null参数值给 allow()deny() 方法,则访问规则将应用到所有的角色,资源和/或权限上。

// 除去 “禁止 staff 修订最近的新闻”(和marketing, 由于继承的原因)
//(等于允许staff修订最近的新闻 Jason注)
$acl->removeDeny('staff', 'latest', 'revise');

echo $acl->isAllowed('marketing', 'latest', 'revise') ?
     "allowed" : "denied";
// allowed

// Remove the allowance of publishing and archiving newsletters to
// marketing
$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

        

如上所示,对于权限的修改可能是增量的,但使用 null 值(未指定权限项的参数值)超越了对权限的增量修改。(所谓的增量修改是指可以对 Resources 一个一个地添加权限或禁止,而如果未指定权限参数值,即使用 null 值,可以使得这些步骤简化,一次性地对某个Resource的所有权限进行允许或禁止。Jason注,Haohappy补)

// 允许 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

        

简介

Comments

1.
$acl->allow('marketing',

array('newsletter', 'latest'),
array('publish', 'archive'));
Can the above statement be rewritten as
2.
$acl->allow('marketing','newsletter',array('publish', 'archive'));
$acl->allow('marketing','latest',array('publish', 'archive'));

I tested it. It didn't give any error but i'm asking this because does 2. will allocate more memory space then 1.?

Regards,
Shah Mubashir Hussain.
1.
$acl->allow('marketing',

array('newsletter', 'latest'),
array('publish', 'archive'));
Can the above statement be rewritten as
2.
$acl->allow('marketing','newsletter',array('publish', 'archive'));
$acl->allow('marketing','latest',array('publish', 'archive'));

I tested it. It didn't give any error but i'm asking this because does 2. will allocate more memory space then 1.?

Regards,
Shah Mubashir Hussain.
any suggestins on how to implement acl in a multitenant system where the roleid is unique within the scope of the tenant. the acl is complaining about the role already being added. i could think of appending the tenantid to the roleid before adding the role to the acl.
I wrote a simple two part tutorial on implementing Zend_Auth and Zend_ACL. Check it out at <a href="http://blog.intervestcorp.com/?p=12">blog.intervestcorp.com</a>.

+ Add A Comment

Please do not report issues via comments; use the ZF Issue Tracker.

If you have a JIRA/Crowd account, we suggest you login first before commenting.

  • BBCode is allowed in the comment markup

  • Select a Version

    Languages Available

    Components

    Search the Manual