Zend_Acl and MVC Integration Part I (Basic Use)
By Aldemar Bernal
So, what is wrong with Zend_Acl and the current MVC implementation in the Zend Framework? there is nothing wrong, it is just that it gets not too obvious for developers how to achieve an optimal integration between these two important parts of the framework.
First at all, this article is based on the following Zend Framework Proporsal (link), by this moment this proposal is in Pending Recommendation state.
Well, how it works? There are two key components in this proposal:
- A Front Controller Plugin: This component resolves if the current user has access to the page which is being opened.
- An Action Helper: This component allows you to check whether the current user has access inside a controller.
Based on these two components, let’s try them with an example. Let’s talk about a website like DevZone, we would need a controller that work with the user management and another one which will deal with article management, as well we need 3 types of users (roles), one for guests, one for writers and another one which will approve the articles; resuming, we have:
Resources:
- user controller.
- article controller.
Roles:
- Guest.
- Writer.
- Admin.
Setting up the Zend_Acl component
After defined what we want to do, the next step will create a Zend_Acl instance which will reflect our model.
/** Creating the ACL object */
require_once 'Zend/Acl.php';
$myAcl = new Zend_Acl();
Creating the roles
Now we create the roles in our Zend_Acl instance.
/** Creating Roles */
require_once 'Zend/Acl/Role.php';
$myAcl->addRole(new Zend_Acl_Role('guest'))
->addRole(new Zend_Acl_Role('writer'), 'guest')
->addRole(new Zend_Acl_Role('admin'), 'writer');
Creating the resources
And then we create the resources needed (one per controller) and their relationship with the roles we created.
/** Creating resources */
require_once 'Zend/Acl/Resource.php';
$myAcl->add(new Zend_Acl_Resource('user'))
->add(new Zend_Acl_Resource('article'));
Creating the permissions
Now that we added the roles and resources to our Zend_Acl instance, it’s time to explain what actions must be available to which roles.
- Guest won’t have access to edit, add or approve an article.
- Writer won’t have access to approve an article.
- Admin will have complete access.
/** Creating permissions */
$myAcl->allow('guest', 'user')
->deny('guest', 'article')
->allow('guest', 'article', 'view')
->allow('writer', 'article', array('add', 'edit'))
->allow('admin', 'article', 'approve');
Creating the access denied view file
We will need to create a view and an action which will address all those denied users, in order to do it, first we create a new action in our error controller:
class ErrorController extends Zend_Controller_Action
{
....
public function deniedAction()
{
}
....
}
And then we create our view file (/application/views/scripts/error/denied.phtml) with some warning message:
<h1>Error</h1>
<h2>Access denied</h2>
<p>You are trying to access an area which you have not allowed.</p>
Finishing the configuration
Okay, we have setup our Zend_Acl configuration, so far, it doesn’t look like something new, but the next step is register the controller plugin, this important part takes the Zend_Acl instance we created and then validates it against the current page being accessed by an user.
/** Setting up the front controller */
require_once 'Zend/Controller/Front.php';
$front = Zend_Controller_Front::getInstance();
$front->setControllerDirectory('path/to/controllers');
/** Registering the Plugin object */
require_once 'Zend/Controller/Plugin/Acl.php';
$aclPlugin = new Zend_Controller_Plugin_Acl($myAcl);
$aclPlugin->setRoleName($currentUserRole);
$front->registerPlugin(new Zend_Controller_Plugin_Acl($acl, 'guest'));
/** Dispatching the front controller */
$front->dispatch();
After this configuration is done, once an user enters in our application, depending the role he/she has the page will be displayed or an access denied page will be displayed.
For more information about this you can go to:
and here is a small implementation source code of this:


19 comments to “Zend_Acl and MVC Integration Part I (Basic Use)”
June 23rd, 2008 at 2:12 pm
Nice writeup, Aldemar! ACLs are often seen as an arcane subject in ZF, and they’re actually dirt simple, as you clearly illustrate. I also like the idea of the deniedAction() in your error controller.
June 24th, 2008 at 7:09 am
I mean from this article and the example code that can be downloaded i can’t figure out the whole big picture. For example what code goes in what place? (bootstrap file? controller file? etc). It is somehow disconnected this code.
June 24th, 2008 at 10:27 am
Nice tutorial.
The problem with Zend_Acl is that nobody wants to hardcode roles, resources and permissions in some file (at least not me). I have database tables for user, roles, resources and permissions, so an admin can easily modify and extend them as needed.
A db-query for the current user and the requested resource (action) is enough to determine rights and let the MVC act accordingly. There is simply no reason to use Zend_Acl as that would just double the db structure and the queries. – Know what I mean?
June 24th, 2008 at 3:26 pm
All the code comes in the bootstrap or wherever you want the Acl to be defined (all but the deniedAction of course). The source code shows you the Use Cases implemented in the proposal, so, you will need to read the UCs to understand that code.
June 24th, 2008 at 3:36 pm
I’ll talk later on in other articles (remember, this was Part I) about more MVC + Zend_Acl, for example to query from a controller if a user has right to edit an article.
Sometimes it’s not necessary to take Acl from a database, for example in a website as the one shown in the article (devzone), there is no moment where an Admin would like Guests to approve articles =P, so, it can be hardcoded. I’m writing right now another article about other proposal I have, that talks about those cases where you need to change Acl in the fly, so, not hardcoded but using anything you’d like (a DB, a config file, etc), stay tuned =D
June 25th, 2008 at 4:21 pm
@grandgeorg
I think you may not have read or understood the ACL documentation because it sounds like you’re trying to use a framework as to not re-invent the wheel yet you rolled your own ALC that reinvented the wheel.
The Zend ACL can be created once, all the resources, roles and perms set up, then serialzed and stored in something like memcached a flat file or DB for increased performance. The backend store can be a database if you wish, you just extend the ACL class and load up your roles, resources and perms from the DB, then loop and add the rights.
June 30th, 2008 at 6:35 pm
The best way I’ve found to use the ACL with a database is to have an on save handler that builds the ACL and serializes it to a cache (Zend_Cache is a handy tool) when the database is updated.
This allows you to store the data in the database, use the Zend_Acl, and Save trips to the DB.
July 1st, 2008 at 6:52 pm
First off, thank you so very much for this
But if I use Doctrine, is it wise to use nested set for roles?
July 8th, 2008 at 6:33 am
Hi mikovali, thanks for your positive feedback, to use nested roles is mostly recommended because not using them could address security flaws since you will have to create permissions for every role you have instead of inherate them, meaning that if you have N roles, you will have to create N*#Resources permissions that will be larger that just inherate permissions, that said, if you 10 roles and 100 resources, you’ll get 1000 permissions instead that maybe 300-400 using nested roles.
About storing acl into a DB, I will talk later about how to integrate datasources into Acl with another proposal I wrote, so stay tuned!.
Aldemar
July 8th, 2008 at 6:39 am
Hi mikovali, thanks for your positive feedback, to use nested roles is mostly recommended because not using them could address security flaws since you will have to create permissions for every role you have instead of inherate them, meaning that if you have N roles, you will have to create N*(Number of Resources) permissions that will be larger that just inherate permissions, that said, if you 10 roles and 100 resources, you’ll get 1000 permissions instead that maybe 300-400 using nested roles.
About storing acl into a DB, I will talk later about how to integrate datasources into Acl with another proposal I wrote, so stay tuned!.
Aldemar
July 9th, 2008 at 12:55 pm
Shouldn’t it be
$front->registerPlugin(new Zend_Controller_Plugin_Acl($aclPlugin, ‘guest’));
?
July 9th, 2008 at 12:55 pm
Shouldn’t it be
$front->registerPlugin(new Zend_Controller_Plugin_Acl($aclPlugin, ‘guest’));
?
July 15th, 2008 at 1:02 pm
It’s a good article for basic use.
but in fact , we can’t do like this in real project.
For advance usage of Zend_Acl , we may combin other components like Zend_Config,Zend_Cache , etc..
July 16th, 2008 at 7:01 pm
You are right, sorry, that’s a typo.
July 16th, 2008 at 7:03 pm
shannonless, the second part of the article is out, hope it helps
http://devzone.zend.com/article/3510-Zend_Acl-and-MVC-Integration-Part-II-Advanced-Use
August 3rd, 2008 at 11:07 am
I have installed Zend Framework 1.5.3.
I created Dir Struct as
Controller/
Models/
Views/
index/
index.phtml
test.phtml
I am able to get the output of index.phtml but when i type
http://localhost/zf/public/test
i am not getting the test file output it shows me error
"Object not found!…"
plz help me to resolve this problem.
Thanx,
with kind regards,
Amit
August 18th, 2008 at 3:06 pm
I have extended the both the Zend_Acl and Zend_Acl_Role_Registry in order to shape the logic into loading only relevant roles and permissions from the database. This took me quite some time because the Zend_Acl class may be configured with relative ease, extending it with a lot of functionality is not.
Is there a simpeler way to load all relevant data from the db into the acl in a lazy manner?
February 12th, 2009 at 6:56 am
When we implement roles using Zend_Acl are static or they are stored in database….
Not able to understand above Tutorial for Zend_Acl-and-MVC-Integration-Part-I-Basic-Use…
April 22nd, 2011 at 7:46 pm
This post was very informative. I just wish that it would show which files the code was in.
I am trying to create ab ACL and used a Action Helper for the logic. How do I register it on the bootstrap file?