Timothy
Timothy

Reputation: 469

How to carry out Yii role based access control when multiples tables are involved

I am now trying to develop a website under the Yii framework and Role-Based Access Control(RBAC) is needed in the program. I read from the guide that filter can be used for RBAC, but I wonder what should I do if the administrators and users are store in two tables? Namely if there are two tables in the database, one for admins and on for users, how should I implemented access control? Thank you.

Upvotes: 3

Views: 1288

Answers (3)

danschmidt5189
danschmidt5189

Reputation: 151

Change How UserID is Stored

I'm current dealing with this exact problem, and my solution was to modify how users IDs are stored in the assignments table. Instead of storing only an integer userID, I store a string indicating the ID and the type of the user:

auth_assignments.userid["<typeId>.<userId>"] VARCHAR(64) NOT NULL

When assigning or checking a role, the user's "authorization ID" is used instead of their normal ID. Would love to hear feedback on this approach.

Upvotes: 0

Raman Shalupau
Raman Shalupau

Reputation: 267

It is posible. However tricky and I cannot guarantee that this would not bring issues in future. What you need is to have two or more tables like AuthAssignment, e.g. AuthAssignment_Admins and AuthAssignment_Customers, and make sure that CDbAuthManager refers to the relevant one each time it is called (e.g. when assigning roles or when checking for permissions).

I'll start from far, but you'll understand why.

  1. We have to create a mechanism that would tell to which table/category does the logged in user belong. This is can be done by extending Yii::app()->user. Explained here. You would want to either add a special param (e.g. authTable) or compara against assigned model.

  2. You have to extend CDbAuthManager. Create a class e.g. CDbAuthManagerTwoTables in components and refer to in in your config.php in authManager as 'class' => 'CDbAuthManagerTwoTables'. In CDbAuthManagerTwoTables

    <?php
    class CDbAuthManagerTwoTables extends CDbAuthManager {
       // public $assignmentTable = 'AuthAssignment'; 
       public $assignmentTable = 'AuthAssignment_Customers'; // you may want to have AuthAssignment_Customers to be your default table
       function __construct() {
          if (!Yii::app()->user->isGuest) {
             if (Yii::app()->user->authTable == 'admin') {
                $this->assignmentTable = 'AuthAssignment_Admins';
             } else {
                $this->assignmentTable = 'AuthAssignment_Customers';
             }
          }
      }
    
      public function setType($assignmentTable = '') { // this method will be needed during authentication
         switch ($assignmentTable) {
           case 'Admin':
             $assignmentTable = 'AuthAssignment_Admins';
             break;
           case 'Customer':
             $assignmentTable = 'AuthAssignment_Customers';
             break;
           default:
             $assignmentTable = 'AuthAssignment_Customers';
             break;
         }
         $this->assignmentTable = $assignmentTable;
      }
    
    }
    
  3. Now assignment upon authentication. We assume that you already have separated login forms and have separate methods in UserIdentity.php. Somewhere in your code you would do:

     $this->setState('authTable', 'admin'); 
    
     $auth = Yii::app()->authManager;  // You should already have this in your code
     $auth->setType('Admin');   // call to our new method from CDbAuthManagerTwoTables
     if (!$auth->isAssigned($user->role, $this->_id)) {
        if ($auth->assign($user->role, $this->_id)) {
           Yii::app()->authManager->save();
        }
     }
    
  4. There is no step 4.

So the same goes for Customers or any other table and authorisation. Let me know how if worked for you.

Upvotes: 3

Narretz
Narretz

Reputation: 4993

I think this is not possible out of the box. When you check the db schema of authassignment, you will see that it has a userid field, which relates to your users table. If you have two different tables, you would need another unique identifier in the auth table. Is it absolutely necessary that you have two different tables for your users? Actually, RBAC is very useful for separating concerns. So you have one user table, but you can assign your users different roles such as "admin", "editor" etc. If you have two different user tables, what do you do if a user becomes an admin? This is complexity that you shouldn't have to handle. If you absolutely have to, you will have to extend the RBAC functionality to make it possible to refer tp different tables.

Upvotes: 2

Related Questions