user3043178
user3043178

Reputation: 23

RBAC Yii2 doesn't work with default roles

I'm following the Definitive Guide to Yii 2.0. In my application I have two roles: the admin, who can do everything and the viewer, who can do some actions that unregistered users can't do. I'm trying to use default roles functionality of Yii 2 RBAC, but it seems doesn't work. The user table in my database has a column named "role": for admin it's value set to 1 and for viewers = 2.

What I did:

/app/rbac/UserGroupRule.php

namespace app\rbac;

use Yii;
use yii\rbac\Rule;

class UserGroupRule extends Rule {
    public $name = 'userGroup';

    public function execute($user, $item, $params) {
        if (!Yii::$app->user->isGuest) {
            $group = Yii::$app->user->identity->role;
            if ($item->name === 'admin') {
                return $group == 1;
            } elseif ($item->name === 'viewer') {
                return $group == 1 || $group == 2;
            }
        }
        return false;
    }
}

$auth = Yii::$app->authManager;

$rule = new \app\rbac\UserGroupRule;
$auth->add($rule);

$author = $auth->createRole('viewer');
$author->ruleName = $rule->name;
$auth->add($viewer);

$admin = $auth->createRole('admin');
$admin->ruleName = $rule->name;
$auth->add($admin);
$auth->addChild($admin, $viewer);

in my controller:

public function behaviors() {
    return [
        'access' => [
            'class' => AccessControl::className(),
            'only' => ['admin'],
            'rules' => [
                [
                    'allow' => true,
                    'actions' => ['admin'],
                    'roles' => ['admin'],
                ],
            ],
        ],
    ];
}

When I try to access "admin" action, it says Forbidden #403, even when I'm an admin. How to make it work?

Upvotes: 2

Views: 5337

Answers (2)

Jason
Jason

Reputation: 336

I was facing the same issue with op. Finally made it work after tinkering with xdebug for a while.

I feel the official documentation on default roles is missing a couple important points, I will summarize them below with some of my personal experiences. The project structure is based on Yii 2.0 Advanced Project Template

Database

user table contains id and group. Where group is type int, 1 for admin and 2 for author

Rules setup

Code simplified for clarity.

The rule class, where you put the actual rule logic.

yii/console/controller/UserGroupRule.php

namespace app\rbac;

use Yii;
use yii\rbac\Rule;

/**
 * Checks if user group matches
 */
class UserGroupRule extends Rule
{
    public $name = 'userGroup';

    public function execute($user, $item, $params)
    {
        if (!Yii::$app->user->isGuest) {
            $group = Yii::$app->user->identity->group;
            if ($item->name === 'admin') {
                return $group == 1;
            } elseif ($item->name === 'author') {
                return $group == 1 || $group == 2;
            }
        }
        return false;
    }
}

Now defining the roles..

yii/console/controller/RbacController.php

namespace console\controllers;

use Yii;
use yii\console\Controller;

class RbacController extends Controller
{
    public function actionInit()
    {
        $auth = Yii::$app->authManager;

        $rule = new \app\rbac\UserGroupRule;
        $auth->add($rule);

        $admin = $auth->createRole('admin');
        $admin->ruleName = $rule->name;
        $auth->add($admin);

        // define 'author' here...
    }
}

After you have this file ready, you should be able to run ./yii rbac/init to generate the rule files:

  • console/rbac/items.php
  • console/rbac/rules.php

Important: You need to place the generated files under your desired application folder, this is crucial. Other wise Yii 2.0 will not be able to pick up the rules. For example: yii/backend/rbac/

Controller and config setup

This is mostly identical to the documentation

yii/commom/config/main.php

Add the following to the return array:

'authManager' => [
    'class' => 'yii\rbac\PhpManager',
    'defaultRoles' => ['admin', 'author'], // your define roles
],  

Now the fun part, under the controller class you would like to apply the rules

yii/backend/controllers/SiteController.php

'access' => [
    'class' => AccessControl::className(),
    'rules' => [
        [
            'allow' => true,
            'actions' => [], // applies to all actions
            'roles' => ['admin'], // your defined roles
        ],
    ],
 ],

Up to this point, the rules should be working. Under your controller class, double check Yii::$app->getAuthManager() see if it contains your defined roles. If not, it means Yii did not pick up the rules correctly, please check previous steps again.

Upvotes: 3

Blizz
Blizz

Reputation: 8400

The user table in my database has a column named "role": for admin it's value set to 1 and for viewers = 2

That's not how it works unfortunately. The rights/roles a user has are (by default) done via the auth_assignment-table. Just add an entry in it:

INSERT INTO `auth_assignment` VALUES ("admin", <user-id>, NOW());

(be sure to change the user ID into whatever user you want to make admin.

That should solve your issue.

Edit (as I misread some of your question):

As per this link you can indeed define default roles, but you have to make sure to also reconfigure your authManager-component in the configuration file to include the default roles:

'components' => [
    'authManager' => [
        // ...
        'defaultRoles' => ['admin', 'viewer'],
    ],
],

This list of roles indicate the permissions that always should be checked for every user, no matter if they have an entry in the auth_assignment-table or not.

Upvotes: 3

Related Questions