It’s important to distinguish between Authentication and Authorization, which I think of as AuthN and AuthZ because… well… syllables.
AuthN identifies a user and decides if they are allowed to visit your site. It is very broad-brush can-you-go-here.
Importantly, it makes an Identity object available for your use in code.
AuthZ is a fine-grain system to decide which resources an authenticated user can gain access to and what they can do with that resource.
@Roridula originally asked about AuthN but needed to be asking about AuthZ.
@allankh and @azothep made the leap to AuthZ but didn’t mention the shift of focus.
If your system’s AuthZ needs were very simple you could satisfy them without installing the AuthZ tools because as @azothep shows, the Identity is available for on-the-spot examination.
But adding AuthZ also adds the can
, canResult
, and scope
methods to the Identity objects and that is the gateway to all the policies.
The questions here have focused on a controller’s index page. In resource terms I think of this as ‘can this actor see an arbitrary list of this record type’.
There’s plenty of named-by-algorithm logic that makes this system work and I think that tripped you up @allankh. You have a canIndex
policy but invoke applyScope
. Your controller should be:
public function index()
{
$users = $this->Users->find();
if (!$this->Authorization->can($users)) {
//redirect unauthorized visitor
}
$this->set(compact('users'));
}
I don’t use the AuthZ component myself so I’m trying to interpret the docs with no use-experience but:
The can()
call’s first argument is the resource you are considering, the second arg is assumed to be the current action. So the call becomes $this->Authorization->can($users, 'index')
(@azothep’s code makes this explicit). And, internally, the current Identity will be used; that’s the current actor/visitor.
I like to make the policy calls using the Identity object because it is clearer to me:
public function index()
{
$users = $this->Users->find();
if (!$this->identity->can('index', $users)) {
//redirect unauthorized visitor
}
$this->set(compact('users'));
}
//in AppController I have
public function identity() {
return $this->getRequest()->getAttribute('identity');
}
One important point regarding the code @azothep and @allankh posted, the can()
policies will return True/False so you need to add something to handle the disallowed cases. I suggested a redirect.
There is a ton more that could be said. But that roughly covers most of the points raised here. But I’ll leave you with this link to the Middleware specifically designed to implement Controller/Action authorization.