Setting Up Authentication using Simple ACL

I'll write about the most common scenario - authentication by username and password and access control to different actions based on user/groups (I'll be using my SimpleAclComponent).

I've changed this component so it doesn't use the cake built-in ACL - it wasn't using the acl functions

To use it you must include the component in your AppController (SimpleAcl has to be before Auth component):

      var $components = array('SimpleAcl', 'Auth');

You have to change some options in AppController beforeFilter():

function beforeFilter()
{
	parent::beforeFilter();
 
	if (isset($this->Auth)) 
	{
		// the authorization type
		$this->Auth->authorize = 'object';
		// here we give the AuthComponent the reference to the object that we want to authorize against 
		$this->Auth->object = &$this->SimpleAcl;
		// get the allowed actions for this controller
		if($this->action != 'login'
		  && ((empty($this->access) || !array_key_exists($this->action, $this->access)))
		  && empty($this->params[Configure::read('Routing.admin')]))
		{
		  $this->Auth->allow();
		}
	 }
}

Authorization

Let's assume we have a role field in out users table that holds the user's group. For simplicity sake we have two groups: User and Admin. Admin is the default group in SimpleACLComponent that has access to everything in the app.

So let's take the PostsController as an example:

class PostsController extends AppController
{
var $name = 'Posts';
var $access = array(
'create' => array('User'),
'edit' => array('User'),
'delete' => array('User'),
);
}

We've defined a basic $access array. This tells SimpleAclComponent that for these 3 actions user must be logged (handled by AuthComponent) and user has to be a member of 'User' group. The read and index actions are not in the array so by default access isn't checked on them - so they can be run by not-logged users too.

Access rules

rules:

  • if the action isn't in $this→access ⇒ allow everybody
  • if the action is in $this→access array ⇒ alow only the groups that are in the array
  • if the actions is an admin action ⇒ allow only ppl in the $admins
  • all actions are allowed for users/groups in $admins array

format of var $access in controller:

var $access = array(
'add' => array('User', 'Moderator'),
'edit' => array('User', 'Moderator'),
'delete' => array('User', 'Moderator'),
);

The source of the component (save as app/controllers/components/simple_acl.php):

<?php 
/**
* SimpleAclComponent
*
* this is a simple authentication component
* the logic is based on the rdAuth by gwoo - thanks for your work!
*
* PHP versions 4 and 5
*
* Copyright (c) Marcin Domanski http://kabturek.info/
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright      Copyright (c) 2007, Marcin Domanski.
* @version        0.8.6117
* @link            http://wiki.kabturek.info/simpleaclcomponent
* @link            http://kabturek.info/
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
*/
class SimpleAclComponent extends Object
{
 
	/**
	* name of the column with the group of the user
	*
	* @var string
	* @access public
	*/
	var $role = 'role';
 
	/**
	* Model that has the user data
	* 
	* @var string
	* @access public
	*/
	var $userModel = 'User';
 
	/**
	* name of the column with the username
	* 
	* @var string
	* @access public
	*/
	var $username = 'username';
 
	/**
	* true if the user is an admin
	* 
	* @var boolean
	* @access public
	*/
	var $admin = false;
 
	/**
	* array of administrators
	*
	* @var array
	* @access public
	*/
	var $admins = array('Admin'); 
 
	/**
	* the access array
	*
	* @var array
	* @access public
	*/
	var $access = array();
 
	/**
	* function that sets the access array 
	*
	* @param string $controllerName name of the controller
	*/
	function initialize($controller)
	{	 
		$vars = get_class_vars('AppController');
		if(!empty($vars['access']))
		{
			$this->access = $vars['access'];
		}
 
		if(!empty($controller->access))
		{
			$this->access = am($this->access, $controller->access);
		}
		return $this->access;
 
	}
 
	/**
	* Function to check the access for the action based on the access list
	*
	* @param array $aro the user 
	* @param string $aco 
	* @param string $acoAction
	* @return boolean
	*/
	function isAuthorized($aro, $controller, $action = null)
	{	 
		//if the user is an admin -> allow
		if( !empty($this->admins) && 
			 ((in_array($aro[$this->userModel][$this->role], $this->admins)
			 	|| in_array($aro[$this->userModel][$this->username], $this->admins)
				|| in_array($aro[$this->userModel]['id'], $this->admins))))
		{
			$this->admin = true;
			return true;
		}
 
		// if the key doesnt exist - allow access
		if (is_array($this->access) && array_key_exists($action, $this->access))
		{
			if(!empty($aro[$this->userModel][$this->role]))
			{	
				if (in_array($aro[$this->userModel][$this->role], $this->access[$action]))
				{
					return true;
				}
				else
				{
					return false; 
				}
			}
			//be sure to check if the user doesnt have the same username as the admin group
			elseif($aro[$this->userModel][$this->username])
			{	
				if (in_array($aro[$this->userModel][$this->username], $this->access[$action]))
				{
					return true;
				}
				else
				{
					return false; 
				}
			}
			elseif($aro[$this->userModel]['id'])
			{	
				if (in_array($aro[$this->userModel]['id'], $this->access[$action]))
				{
					return true;
				}
				else
				{
					return false; 
				}
			} 
			else 
			{
				return false; 
			}
		}
 
		// if the action is an admin action and the user isnt an admin and the permissions for the action werent
		// defined
		if(strpos($action, Configure::read('Routing.admin')) === 0)
		{
			return false;
		}
 
		return	true;
	}
 
}?>
 
simpleaclcomponent.txt · Last modified: 2007/12/05 11:56 by kabturek
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki