Luc
Luc

Reputation: 392

Yii2 Restricted AccessControlFilter Logic

After playing around with yii2 Access Control Filter i came around this Answer, which helps me a lot. I tried to restrict the access by doing the following:

Based on this tutorial i created a AccessRule. I added the following logic.

...
// Check if the user is logged in, and the roles match
} elseif (!$user->getIsGuest() && $role === '#' && $user->can("admin")) {
    return true;
} elseif (!$user->getIsGuest() && $role === '~' && $user->can("admin")) {
    return true;
}
...

Whereas the $user->can("admin") method comes from this simple yii2 user authentication module.

So i my idea is to restrict everthing by default and open actions/sides if needed.

I added the following to my config (web.php)

...
'as beforeRequest' => [
    'class' => 'yii\filters\AccessControl',
    'ruleConfig' => [
                'class' => 'app\components\AccessRule'
            ],
    'rules' => [
        [
            'allow' => true,
            'roles' => ['#'],
        ],
        ...

That means, the User which has the Role Admin is allowed to do everything. Every other roles/users (guests, @ or ~ (logged in but no admin role)) aren't allowed to do anything by now.

Of course a user with role ~ should be allowed to do some stuff. So I opened up the permission for one controller and added the following behavior

public function behaviors()
{
    return [
         'access' => [
            'class' => AccessControl::className(),
            'ruleConfig' => [
                'class' => AccessRule::className()
            ],
            'only' => ['index'],
            'rules' => [
                [
                    'actions' => ['index'],
                    'allow' => true,
                    'roles' => ['~'],
                ],
            ],
        ],
...

Unfortanatly the user with the role ~ still can't access the action index for that spezified controller.

So is my logic/thinking inappropriate?

Is the problem the sequence calling for the Access Control Filters?

Upvotes: 1

Views: 492

Answers (1)

Rahul Pawar
Rahul Pawar

Reputation: 1036

I do like this :

$GLOBALS['role'] = json_decode(Yii::$app->session->get('ROLES'), TRUE); // my roles

and this is my behaviours() function :

public function behaviors() {
        return [
            'access' => [
                'class' => \yii\filters\AccessControl::className(),
                'only' => ['create', 'update', 'delete', 'index', 'profile', 'timeline', 'upload'],
                'rules' => [
                    [
                        'actions' => ['index', 'view', 'create', 'update', 'delete', 'profile', 'timeline', 'upload'],
                        'allow' => true,
                        'roles' => ['@'],
                        'matchCallback' => function() {
                            return ($this->CheckPermission()) ? TRUE : $this->redirect(['site/errorpage']);
                        },
                    ],
                ],
            ],
        ];
    }

And after than I create CheckPermission() function :

protected function CheckPermission() {
        $action = $this->action->id;

        switch ($action) {
            case 'create':
                if ($GLOBALS['role'][90])
                    return TRUE;
                break;
            case 'update':
                if ($GLOBALS['role'][91])
                    return TRUE;
                break;
            case 'delete':
                if ($GLOBALS['role'][92])
                    return TRUE;
                break;
            case 'index':
                if ($GLOBALS['role'][93])
                    return TRUE;
                break;

            default: return TRUE;
        }
        return FALSE;
    }

If check permission return true then user is authorized otherwise user is not authorized.

Upvotes: 1

Related Questions