======= 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):
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;
}
}?>