cakephp 3.0 isAuthorized() not being called

2019-08-03 15:15发布

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);
    }
}

3条回答
Juvenile、少年°
2楼-- · 2019-08-03 15:56

From cakephp 3.x documentation: you can configure authorization handlers in your controller’s beforeFilter() or initialize() methods using an array:

// Basic setup
$this->Auth->config('authorize', ['Controller']);

// Pass settings in
$this->Auth->config('authorize', [
'Actions' => ['actionPath' => 'controllers/'],
'Controller'
]);
查看更多
Animai°情兽
3楼-- · 2019-08-03 16:02

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 the add method to be accessed by everyone (it won't even require authentication):

$this->Auth->allow(['logout', 'add']);

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 and unauthorizedRedirect options, see Cookbook > Components > Authentication > Configuration options

查看更多
放荡不羁爱自由
4楼-- · 2019-08-03 16:11

As 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":

'authorize' => array('Controller'),

so the code should looks something like this:

$this->loadComponent('Auth', [
    'loginRedirect' => [
        'controller' => 'Articles',
        'action' => 'index'
    ],
    'logoutRedirect' => [
        'controller' => 'Pages',
        'action' => 'display',
        'home'
    ],
    'authorize' => array('Controller'),                
]);

Hope it help some one saving time :)

查看更多
登录 后发表回答