How to organize and manage an ACL?

2019-05-25 00:57发布

问题:

Taking the Zend_ACL as my example, I'm wondering how this should be organized for a project. Sure the example is all nice and neat, but a real site is much more complex.

$acl = new Zend_Acl();

$acl->addRole(new Zend_Acl_Role('guest'));
$acl->addRole(new Zend_Acl_Role('member'));
$acl->addRole(new Zend_Acl_Role('admin'));

$parents = array('guest', 'member', 'admin');

$acl->addRole(new Zend_Acl_Role('someUser'), $parents);

$acl->add(new Zend_Acl_Resource('someResource'));
$acl->deny('guest', 'someResource');
$acl->allow('member', 'someResource');

echo ($acl->isAllowed('guest', 'someResource') ? 'allowed' : 'denied');

Given that each controller/page on my site will have some kind of access checking I need the rules to be globally available. Does this mean that I need to create a massive config file or class to setup all the rules on load? Wouldn't that waste a lot of memory?

Yet if I only setup the rules needed for each controller that would defeat the purpose of the ACL right? The main reason for using a ACL is to avoid having permissions spread throughout the codebase like this:

Admin_Controller
{
    public function action()
    {
        if($user->role !== 'admin')
        {
            die('not allowed');
        }
    }
}

What about changes? What if the ACL rules are stored in a database where an administrator can easily change permissions. Should they all be downloaded each page request? Wouldn't that put a large burden on the system?

In short, how does an ACL work on a large site? What problems occur? How are cascading permissions handled?

回答1:

You could store the roles in a database and cache the object in memory using memcache so that you'd only have to query the db when new roles are added or changed. As far as implementing the ACL, since it'll be used system-wide, you can initialize it in your Bootstrap.php file and then store the object in Zend_Registry so that it is accessible to your whole app.

Applying these rules can happen at various points. You may want to apply the routes in a custom router or perhaps at a higher level at the controller level. If you extend Zend_Controller_Action, you can put your ACL rules in this master controller from which every other controller is derived. You can check ACL permissions in the _init() method. There maybe other points in the system where you need the ACL or would want to check it, depending on what and how you're building it (that's why you're storing the ACL in the registry).