Auth and ACL an end to end tutorial pt. 1

Now, there are many tutorials out there for Auth and ACL in CakePHP. However, none of them (as far as I know of) cover putting together Auth and ACL from beginning to end. That is what I’m going to do in this article. I am splitting the article into two parts; the first about setting up our app and getting the Aros running, the second on building Acos and putting it all together.

With that said, this article assumes you know the basics of CakePHP, and are familiar with all of the MVC core concepts. You are also comfortable using bake and the cake console. If not, learn those concepts first, and then come back. After learning these concepts everything else will make more sense. This tutorial will also use Auth in actions mode, this authenticates our ARO – groups and users – against the ACO objects – controllers & actions.

Tabula rasa

I am going to start with a blank install of cake that has just been checked out / unpacked, and has haddatabase.php config file setup and the Security.salt value changed to remove the warning. If you have an app in progress that should work as well, but you will have to make adjustments for the user, and group models accordingly.


First things first, we need to make some tables to base our application off of. We are going to create tables for users, groups, posts and widgets. This will give us a few things we can try our ACL system against.

Show Plain Text

  1. CREATE TABLE users (
  3.     username VARCHAR(255) NOT NULL UNIQUE,
  4.     password CHAR(40) NOT NULL,
  5.     group_id INT(11) NOT NULL,
  6.     created DATETIME,
  7.     modified DATETIME
  8. );
  9. CREATE TABLE groups (
  11.     name VARCHAR(100) NOT NULL,
  12.     created DATETIME,
  13.     modified DATETIME
  14. );
  15. CREATE TABLE posts (
  17.     user_id INT(11) NOT NULL,
  18.     title VARCHAR(255) NOT NULL,
  19.     body TEXT,
  20.     created DATETIME,
  21.     modified DATETIME
  22. );
  23. CREATE TABLE widgets (
  25.     name VARCHAR(100) NOT NULL,
  26.     part_no VARCHAR(12),
  27.     quantity INT(11)
  28. );

These are the tables I used to build the rest of this article, so get them into your database if you are playing at home. Once we have the table structure in the db we can start cooking. Bake up the models, controllers, and views. Leave out admin routing for now, this is a complicated enough subject without them. Also be sure not to add either the Acl or Auth Components to any of your controllers, we’ll be doing that soon enough. You should now have models, controller, and baked views for your users, groups, posts and widgets.

Preparing the application for Auth and Acl

We now have a functioning CRUD application. Bake should have setup all the relations we need, if not do that now. There are a few other pieces that need to be added before we can add components. First add a login and logout action to your UsersController.

Show Plain Text

  1. function login() {
  2.     //Auth Magic
  3. }
  4. function logout() {
  5.     //Auth Magic
  6. }

We don’t need to worry about adding anything to hash passwords, as Auth will do this for us automatically when creating/editing users, and when they login. Furthermore, if you hash the passwords manually Auth will not be able to log you in at all.


Next we need to make some modifications to AppController. If you haven’t made one in app/ do so now. Since we want our entire site controlled with Auth and Acl, we will set them up in our AppController. Add the following to AppController:

Show Plain Text

  1. var $components = array(‘Auth’, ‘Acl’);
  2. function beforeFilter() {
  3.     //Configure AuthComponent
  4.     $this->Auth->authorize = ‘actions’;
  5.     $this->Auth->loginAction = array(‘controller’ => ‘users’, ‘action’ => ‘login’);
  6.     $this->Auth->logoutRedirect = array(‘controller’ => ‘users’, ‘action’ => ‘login’);
  7.     $this->Auth->loginRedirect = array(‘controller’ => ‘posts’, ‘action’ => ‘add’);
  8. }

We also need to add a few temporary overrides to the groups and users controllers. Add the following to boththe users and groups controllers.

Show Plain Text

  1. function beforeFilter() {
  2.     parent::beforeFilter();
  3.     $this->Auth->allowedActions = array(‘*’);
  4. }

These overrides shut off the Auth component so we can actually get some data in our tables. If we left this out, Auth would do its job and lock us out. Not very useful.

Initialize the Acl

Before we can start using the Acl we need to initialize it. If you try to view any pages right now, you will get a missing table error, so lets get rid of that. In a shell run the following cake schema run create DbAcl and follow the prompts to drop and create the tables.

With the controllers setup for data entry, and the Acl tables initialized we are ready to go right? Not entirely, we still have a bit of work to do in the user and group models. Namely, making them auto-magically attach to the Acl.

Acts As a Requester

Auth stores information about the currently logged in user in the Session, however we are building an Access Control System based on groups. Therefore, we need to associate our users to our groups in the Acl. In order to do this we can use the AclBehavior. The AclBehavior allows for the automagic connection of models with the Acl tables. Its use requires an implementation of parentNode() on your model. In our User model we will add the following.

Show Plain Text

  1. var $actsAs = array(‘Acl’ => array(‘requester’));
  2. function parentNode() {
  3.     if (!$this->id && empty($this->data)) {
  4.         return null;
  5.     }
  6.     $data = $this->data;
  7.     if (empty($this->data)) {
  8.         $data = $this->read();
  9.     }
  10.     if (!$data[‘User’][‘group_id’]) {
  11.         return null;
  12.     } else {
  13.         return array(‘Group’ => array(‘id’ => $data[‘User’][‘group_id’]));
  14.     }
  15. }

Then in our Group Model Add the following:

Show Plain Text

  1. var $actsAs = array(‘Acl’ => array(‘requester’));
  2. function parentNode() {
  3.     return null;
  4. }

What this does, is tie the Group and User models to the Acl, and tell CakePHP that every-time you make a User or Group you want an entry on the aros table as well. This makes Acl management a piece of cake as yourAROs become transparently tied to your users and groups tables.

So now our controllers are prepped for adding some initial data, and our Group and User models are bound to the Acl table. So add some groups and users. I made the following groups:

  • administrators
  • managers
  • users

I also created a user in each group so I had some different users to test with later. Write everything down or use easy passwords so you don’t forget. If you do a SELECT * FROM aros; from a mysql prompt you should get something like the following:

Show Plain Text

  1. +—-+———–+——-+————-+——-+——+——+
  2. | id | parent_id | model | foreign_key | alias | lft  | rght |
  3. +—-+———–+——-+————-+——-+——+——+
  4. |  1 |      NULL | Group |           1 | NULL  |    1 |    4 |
  5. |  2 |      NULL | Group |           2 | NULL  |    5 |    8 |
  6. |  3 |      NULL | Group |           3 | NULL  |    9 |   12 |
  7. |  4 |         1 | User  |           1 | NULL  |    2 |    3 |
  8. |  5 |         2 | User  |           2 | NULL  |    6 |    7 |
  9. |  6 |         3 | User  |           3 | NULL  |   10 |   11 |
  10. +—-+———–+——-+————-+——-+——+——+
  11. 6 rows in set (0.00 sec)

This shows us that we have 3 groups and 3 users. The users are nested inside the groups, which opens up the possibility of setting per-user permissions.

One thing I noticed when making this tutorial, is that if you modify a User’s group it does not modify their Aro. You have to do that separately it seems.

So that concludes the first part of this series. We now have a users/groups system bound for the most part to the Acl (see above). Up next getting our controllers and actions into the acos table and getting everything to jive together. Also, at the end of this process I will be making all the files I used to build this tutorial with all the SQLdumps available for your perusal.

Leave a Reply