It’s been a rough ride but I think I’m finally getting the hang of CakePHP‘s AclComponent. The official documentation kind of sucks, unless you’re a Lord of the Rings fan. Great, but how do I apply this in a real world application.
I needed full role-based access control in a -application I’m working on. In the end I did find an elegant way to do it with Cake’s ACL implementation.
It doesn’t surprise me that many Cake users have built solutions of their own (like Studio Canaria) or have decided to copy the solution from the ACL blog tutorial where users can have only one role (like Gilang, lemoncake, or realm3). That’s fine if in your application you never need more than one role per user, but this was not my case.
Why role-based access control?
In role-based access control roles are sets of permissions to perform operations. Application users are given access to roles instead of individual permissions. Since the user-to-permission assignment is now decoupled through the role, doing things like promoting a user from to an admin becomes easy.
Note that the definition of which permissions go with which role doesn’t have to be configurable. Things like record-level protection, where a user to edit a post only if she is the post’s owner, might even be impossible to do through ACL only. (Related video: Zed Shaw – The ACL is Dead) The permission-to-role assignment may have to be hard-coded in the application logic. Guess what: it often is.
Roles in CakePHP’s ACL
Since you are reading this you probably already know that CakePHP’s ACL consists of trees of AROs and ACOs, and of relationships between them. You’ll recall that AROs are “access request objects,” i.e. who we want to protect the ACOs from. ACOs are “access control objects,” i.e. what we want to protect.
You might think that roles should be AROs because “they access stuff.” In RBAC roles are sets of permissions, and users want to access the roles. Now users are AROs, and roles are ACOs. (Edward A. Webb has a similar system but doesn’t call it RBAC.)
For example, suppose we are constructing a forum system. Immediately we detect sets of permissions to use in access control: creating forums and changing system settings (admin role), dealing with spam and misbehaving users (mod role), and creating new topics and posts (user role).
ACOs make a tree, they can be nested. Nesting means that we can make subroles that give only a part of the permissions. For example if we define the user role within the mod role, users with mod role automatically get access to the normal user stuff. For the sake of the example let’s make the admin role unrelated. Now having the admin role doesn’t automatically give you the right to ban users or post new topics. It might not make sense in a realworld forum but let’s do it anyway just to make things more interesting.
This role structure is easily created with the AclShell:
cake acl create aco / Forum cake acl create aco Forum Mod cake acl create aco Mod User cake acl create aco Forum Admin
Now the user’s access to a particular role can be checked with something like
$this->Acl->check($aro, 'Forum/Mod', '*')
That’s really all there is to it. Coming up next: Full CakePHP Auth + ACL tutorial.