Help Me Understand Rbac Accessrules

Hi guys, I’m trying to understand the usage of accessRules in RBAC especially the actions, users and roles part.

  1. What is the difference between actions in accessRules and RBAC operations? Assuming I have create, read, update, delete and approve action in a controller, do I have to create 5 operation (create, read, update, delete and approve) in RBAC as well?

  2. What is the difference between users and roles in accessRules? Is users specifically refers to user name while roles refers to the user roles created in RBAC?

  3. Which part of the accessRules do we specify the operation name we created when we define the authorization hierarchy?

Let’s assume I have the following actions in my Article controller:


- index

- create

- read

- update

- delete

- admin

- approve

And 2 types of user group:


- member

- administrator

My RBAC structure would be like this (am I correct?)


// Article operations

$auth->createOperation('createArticle', 'Create an article');

$auth->createOperation('updateArticle', 'Update article');

$auth->createOperation('deleteArticle', 'Delete an article');

$auth->createOperation('adminArticle', 'Admin article');

$auth->createOperation('approveArticle', 'Approve an article');


// moderator roles

$role = $auth->createRole('member', 'User with user member permissions');

$role->addChild('createArticle');


// admin roles

$role = $auth->createRole('admin', 'User with user administration permissions');

$role->addChild('createArticle');

$role->addChild('updateArticle');

$role->addChild('deleteArticle');

$role->addChild('adminArticle');

$role->addChild('approveArticle');

Then at accessRules I would have the following:


public function accessRules()

{

        return array(

                array(

                        'allow',

                        'actions' => array('index', 'view'),

                        'users' => array('*')

                ),

                array(

                        'allow',

                        'actions' => array('create'),

                        'roles' => array('member')

                ),

                array(

                        'allow',

                        'actions' => array('create', 'admin', 'update', 'delete', 'approve'),

                        'roles' => array('admin')

                ),

                array(

                        'deny',

                        'users' => array('*')

                )

        );

}

Am I doing it correctly for the above? I still cannot figure out where I should place the operation name defined in authorization hierarchy.

Thanks.

First check guide and this wiki article.

To have maximal flexibility it is better to define RBAC operations for each controller action.

This way you will not have to change both RBAC hierarchy and "accessRules" in controllers when you change something.

But this depends on concrete situation. For example: you have "index" action to show a list of articles and "view" to view one article. Also you know that if the user has an access to "index" action then he definitely should have an access to "view" (and vice versa). In such case you can define single "viewArticle" RBAC operation and assign it to both "index" and "view" controller actions.

Yes, users refer to user name and also to can have some special values:

This can be useful in simple cases where you have a special ‘admin’ user and ‘other’ users.

So you can set ‘users’=>array(‘admin’) for admin actions and use special values (*,?,@) in other cases.

And if you have several groups of users then it is better to use roles.

You need to use operations in accessRules, not roles. Role represents a group of operations and role assigned to the user, so user have access to all included operations. And on the controller level you specify operations and access will be checked for a concrete user per operation through assigned role.

Yes, the hierarchy looks good.

Note that you need to define this hierarchy only once and save it and you should not run code above on each request.

If you use db auth manager then you can call $auth->save() at the end (but remember that you need to do this only once after you change RBAC structure).

This part is actually a separate topic and depends on what you choose to use - db auth manager or php auth manager. Also there are several extensions which implement UI for RBAC, but I never used them (I usually use php auth manager and edit auth file manually).

As (I hope) you understand from the above the accessRules should be this:


public function accessRules()

{

        return array(

                array(

                        'allow',

                        'actions' => array('index', 'view'),

                        'users' => array('*') // you can leave it this way if you do not plan 

                                              // to restrict access to these actions

                ),

                array(

                        'allow',

                        'actions' => array('create'),

                        'roles' => array('createArticle')

                ),

                array(

                        'allow',

                        'actions' => array('update'),

                        'roles' => array('updateArticle')

                ),

                array(

                        'allow',

                        'actions' => array('delete'),

                        'roles' => array('deleteArticle')

                ),

                array(

                        'allow',

                        'actions' => array('approve'),

                        'roles' => array('approveArticle')

                ),

                array(

                        'allow',

                        'actions' => array('admin'),

                        'roles' => array('admin') //role also can be used

                ),

                array(

                        'deny',

                        'users' => array('*')

                )

        );

}

Note that for ‘index’ and ‘view’ you can have ‘users’=>’*’ if you do not plan to restrict access here.

For other actions there are ‘roles’=>array(‘operation_name’).

For ‘admin’ action there is ‘roles’=>array(‘admin’) - you can use role here and not operation (or if you want to have more flexibility and be able to give an access to ‘admin’ action to several roles than you can use ‘adminArticle’ operation here).

It is a bit confusing but actually RBAC’s roles, tasks and operations exit more on the logical level - in the code they are basically the same thing. So you when you define ‘accessRules’ method you can use RBAC operation name of role name or task name.

Hi seb, thanks for the great clarification. I have upvoted your reply. Thank you!

Hi. My question in this thread is similar. Wondering if you might take a look and try to help me understand what I’m missing?

I’ve read both guide and wiki several times over, and I thought I understood how the parent/child relationships work, but I can’t figure out what shape the accessRules() should take.