Friday, December 7, 2012

Role based authentication in Cake 2.x

I do not like reinventing the wheel so really just want to build on existing tutorials and provide some background information and experience.

 Firstly make sure you understand the difference between ACO and ARO. To put it in very simple terms an ACO is something that is protected by ACL and an ARO is something that uses ACL to access the ACO.

 It might help to think of ARO as users (groups) and ACO as controller actions. You will be marking your user and group models as requester objects and setting ACO on controller actions across the board.

The Cake manual really is good in explaining the concept of ARO, ACO, ACL. Please make sure you read it and understand it before continuing.  Unless you understand what ARO, ACO, and ACL mean at this point the rest of this post will make no sense.

Please RTFM before continuing.

Okay, now read through the Cake page that introduces the ACL shell (here). Ignore the sections "Create and delete nodes" and "Grant and Deny Access". We will be using tools to do these tasks since manually assigning permissions for even a medium sized project (20 models) would be unmanageable - especially if you are using a feature driven Agile approach.

Read and preferably try out the tutorial found on the Cake book site (here). Following this tutorial will give you a role based authentication system. Since we are predominantly interested in Role Based Authentication please make sure that you follow the instructions regarding "Group-only ACL" (here).

Still with me? Okay - I typically use a feature driven Agile approach when developing. CakePHP really lends itself to this development methodology. BUT it does mess around a bit with ACL when you need to add new models and controller methods. So what's the fix?

Well, in my opinion, the AclExtras plugin (available here) that the tutorial I linked to earlier is an indispensable tool. By using it to sync the ACO table (read the tutorial) you can quickly create/recreate the ACO tree.  Now you should understand why I told you to ignore the section "Create and delete Nodes" from the Shell Manual.

Go back to the page about the ACL shell (here). At the bottom of the page there are instructions to output the tree. I personally like to output it into a text file and store it in my documents folder. Not only is it useful to have a list of the ACO's but it really helps in creating the initDB method in the Users controller (see the tutorial).

 Please don't make the mistake of making every model an ARO. Only the User/Group tables need to be ARO. The tutorial doesn't explicitly say this and I remember the first time I worked with ACL I made this mistake. Do not copy and paste the ActsAs requester into each model!

Development is never static (unless you are using a Waterfall approach in a legacy environment like Cobol or Fortran). So working with ACL in CakePHP will require some tweaking as you go along.

 Fixing the ARO table is relatively simple. There are a couple of ways to fix it:

1) Truncate the table, add the allow method from the tutorial to your before filter in Users controller and add new users who are linked to the appropriate groups. Remember: We are focused on role based authentication so you should have assigned group as parent to user.
2) Truncate the table and manually add the groups required (should only be a handful)

Once you have fixed your ARO table you should rerun the initDB method in your Users controller to recreate the join table (aros_acos). I'm not sure why this join table is named in such a way as to break Cake conventions but truncating it and rerunning your initDB method (see the tutorial) is the way to fix permissions.

What happens if you get a node error? No problem really - resync your ACO table with AclExtras plugin (see tutorial). When will this occur? If you add a new controller, or a new method to a controller. This is why I use the ACL shell (linked above) to export the ACO tree (created with AclExtra's plugin). It allows me to quickly check what nodes exist.

What do the tables do?

  1. 'acos' => objects that can be requested by ARO
  2. 'aros' => requester objects that require access to protected ACO
  3. aros_acos => join table linking the permissions
In the tutorial linked above the initDB method sets up the 'aros_acos' join table.

Any questions?  Please comment on the post and I will answer.

No comments:

Post a Comment