I've followed the tutorial and all the CakePHP Authorization guide and I can't get my isAuthorized() method to be called. My understanding (correct me if I am wrong, which is incredibly likely) is by delegating authorize to the specific controllers by doing 'authorize'->['Controller']
in AppController.php
, when a method in UsersController is called, in this case 'add', UsersController would run the isAuthorized()
method I defined. I was testing to see if this method ran at all outputting a flash->error message right when isAuthorized()
is called but nothing happens. If I explicitly call isAuthorized($hardcodeduser)
in my beforeFilter()
method it will work but only if I hard code a user.
The way the method is supposed to work is: If a registered user requests to add/create a new user, the system checks to see if the user has admin/staff level permissions (which is just a 0 or 1 value in the database) and if the user does not have permission then it redirects to the home screen with an error message that says "You are not authorized to access that function".
Any help or suggestions or other links to follow would be much appreciated!
class AppController extends Controller {
public $components = ['Flash', 'Auth', 'Session'];
public function initialize() {
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize' => ['Controller'],
'loginRedirect' => [
'controller' => 'Articles',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
]
]);
}
public function beforeFilter(Event $event) {
$this->Auth->authorize = 'Controller';
}
public function isAuthorized($user) {
if(isset($user['is_staff']))
return true;
return false;
}
}
class UsersController extends AppController {
public function beforeFilter(Event $event) {
parent::beforeFilter($event);
$this->Auth->allow(['logout']);
}
public function isAuthorized($user) {
$this->Flash->error(__('Test Message PLEASE WORK'));
if($this->request->action === 'add') {
$isStaff = $user['is_staff'];
if($isStaff == 0) {
$this->redirect($this->Auth->redirectUrl());
$this->Flash->error(__('Not authorized to access this function'));
return false;
}
}
return parent ::isAuthorized($user);
}
}
From cakephp 3.x documentation: you can configure authorization handlers in your controller’s beforeFilter() or initialize() methods using an array:
Generally your assumption is correct,
Controller::isAuthorized()
is going to be invoked automatically when using the controller authorization handler.The problem with your code is that in your
UsersController::beforeFilter()
method you are explicitly allowing theadd
method to be accessed by everyone (it won't even require authentication):You have to understand that once a method is allowed, there will be no further checks made by the auth component, see AuthComponent::startup().
Also note that you don't need to redirect and set a flash message manually, the component will do that for you, you just need to configure it appropriately using the
authError
andunauthorizedRedirect
options, see Cookbook > Components > Authentication > Configuration optionsAs we following the Cake blog tutorial, they made a little mistake, that function "isAuthorized" never be called. And I did take a time to research it. Solution is Adding this line when load component "Auth":
so the code should looks something like this:
Hope it help some one saving time :)