天天看点

YII framework下基于角色的访问控制(RBAC)

yii下,filters()和accessControl()是YII基本的访问控制体系,

public function filters(){

    return array(

           'accessControl',

    );

}

public function accessControl(){

    return array(

        array(

            'allow', //allow or deny 允许或者拒绝

            'controllers' => array('controllersList'), //对控制器进行访问控制

            'actions' => array('actionsList'), //对action进行访问控制

            'users' => array('usersList'), //对用户

            'roles' => array('roles'), //对角色

            'ips' => array('ip 地址'), //对客户端地址

            'verbs' => array('GET','POST'), //对客户端的请求方式

            'expression' => '' //对表达式(一般是业务逻辑)

            'message' => 'thank your access', //错误信息提示,一般是deny时用到

         ),

       array(....),

       ....

       array('deny', users => array('*')),

    );

}

好了,有了以上的访问控制,我们针对上面的roles进行讨论RBAC。

Yii的RBAC是基于一个组件authManager的,可以先在main。php中配置authManager

authManger分为基于数据库的和基于PHP脚本的,一般如果你的应用程序基于数据库(mysql或者pgsql),最好把authManger配置为CDbAuthManger,而不是CPhpAuthManger。

...

'authManager' => array(

     'class' => 'CDbAuthManager',

     'connectionID' => 'db',

),

'db' => array(...),

...

配置好了以后,需要在数据库中增加3个存放RBAC规则的表:

AuthItem -- 存放建立的授权项目(role、task或者opration)

AuthItemChild -- 存放授权项目的继承关系

AuthAssignMent -- 存放用户和授权项目的关系表

  1. CREATE TABLE `authitem` ( 
  2.             `name` varchar(64) NOT NULL, 
  3.             `type` int(11) NOT NULL, 
  4.             `description` text, 
  5.             `bizrule` text, 
  6.             `data` text, 
  7.             PRIMARY KEY (`name`) 
  8.           ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  1. CREATE TABLE `authitemchild` ( 
  2.                  `parent` varchar(64) NOT NULL, 
  3.                  `child` varchar(64) NOT NULL, 
  4.                  PRIMARY KEY (`parent`,`child`), 
  5.                  KEY `child` (`child`), 
  6.                  CONSTRAINT `authitemchild_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `authitem` (`name`) ON DELETE CASCADE ON UPDATE CASCADE, 
  7.                  CONSTRAINT `authitemchild_ibfk_2` FOREIGN KEY (`child`) REFERENCES `authitem` (`name`) ON DELETE CASCADE ON UPDATE CASCADE 
  8.                ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  1. CREATE TABLE `authassignment` ( 
  2.                   `itemname` varchar(64) NOT NULL, 
  3.                   `userid` varchar(64) NOT NULL, 
  4.                   `bizrule` text, 
  5.                   `data` text, 
  6.                   PRIMARY KEY (`itemname`,`userid`), 
  7.                   CONSTRAINT `authassignment_ibfk_1` FOREIGN KEY (`itemname`) REFERENCES `authitem` (`name`) ON DELETE CASCADE ON UPDATE CASCADE
  8.                 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

建好表以后,就可以用Yii提供的authManger组件的API建立相关的授权项目,并指定授权关系了。

下面是一个例子:

下面做一个实例:

YII framework下基于角色的访问控制(RBAC)
我们要实现上面的授权关系。
  1. class AuthManagerController extends Controller {
  2.     public function actionIndex(){
  3.         $auth = Yii::app()->authManager;
  4.         if ($auth !== NULL){
  5.             $auth->clearAll();
  6.             //create roles
  7.             $roleOwner = $auth->createRole('owner');
  8.             $roleReader = $auth->createRole('reader');
  9.             $roleMember = $auth->createRole('member');
  10.             $roleBlackList = $auth->createRole('blackList');
  11.             //create operations
  12.             //issues
  13.             $auth->createOperation('createIssue', 'create issue in project');
  14.             $auth->createOperation('readIssue', 'read issue');
  15.             $auth->createOperation('updateIssue', 'update issue');
  16.             $auth->createOperation('deleteIssue', 'delete issue');
  17.             //projects
  18.             $auth->createOperation('createProject', 'create a new project');
  19.             $auth->createOperation('readProject', 'read project');
  20.             $auth->createOperation('updateProject', 'update project');
  21.             $auth->createOperation('deleteProject', 'delete project');
  22.             //users
  23.             $auth->createOperation('createUser', 'create a new user');
  24.             $auth->createOperation('readUser', 'read user');
  25.             $auth->createOperation('updateUser', 'update user');
  26.             $auth->createOperation('deleteUser', 'delete user');
  27.             //authorization
  28.             $roleReader->addChild('readIssue');
  29.             $roleReader->addChild('readProject');
  30.             $roleReader->addChild('readUser');
  31.             $roleMember->addChild('reader');
  32.             $roleMember->addChild('createIssue');
  33.             $roleMember->addChild('updateIssue');
  34.             $roleMember->addChild('deleteIssue');
  35.             $roleOwner->addChild('reader');
  36.             $roleOwner->addChild('member');
  37.             $roleOwner->addChild('createProject');
  38.             $roleOwner->addChild('updateProject');
  39.             $roleOwner->addChild('deleteProject');
  40.             $roleOwner->addChild('createUser');
  41.             $roleOwner->addChild('updateUser');
  42.             $roleOwner->addChild('deleteUser');
  43.             //assign
  44.             //此时,在Issue中的rules中设置view和index的roles=>array('member'),不管是什么用户,都无法访问这两个action
  45.             $userAdmin = User::model()->findByAttributes(array('username' => 'admin'));
  46.             $auth->assign('owner', $userAdmin->id);
  47.             $auth->assign('member', $userAdmin->id); //将用户名为admin(id=3)指定为member角色,这样就可以访问了。
  48.             $auth->assign('reader', $userAdmin->id);
  49.             $userDemo = User::model()->findByAttributes(array('username' => 'demo'));
  50.             $auth->assign('member', $userDemo->id); //将用户名为admin(id=3)指定为member角色,这样就可以访问了。
  51.             $auth->assign('reader', $userDemo->id); //将用户名为demo(id=4)指定为reader角色
  52.             $userDemo2 = User::model()->findByAttributes(array('username' => 'demo2'));
  53.             $auth->assign('reader', $userDemo2->id); //将用户名为demo(id=4)指定为reader角色
  54.             $userBlackList = User::model()->findByAttributes(array('username' => 'demo3'));
  55.             $auth->assign('blackList', $userBlackList->id);
  56.         }else{
  57.             $message = 'Please config your authManage as a compontion in main.php';
  58.             throw new CHttpException(0, $message);
  59.         }
  60.     }
  61. }
建立授权关系以后,更新accessRules为:
  1. public function accessRules()
  2.     {
  3.         return array(
  4.             array('allow', // allow all users to perform 'index' and 'view' actions
  5.                 'actions'=>array('index','view'),
  6.                 'users'=>array('@'),
  7.                                 'roles' => array('member', 'owner', 'reader'),
  8.             ),
  9.             array('allow', // allow authenticated user to perform 'create' and 'update' actions
  10.                 'actions'=>array('create','update'),
  11.                 'users'=>array('@'),
  12.                                 'roles' => array('member', 'owner'),
  13.             ),
  14.             array('allow', // allow admin user to perform 'admin' and 'delete' actions
  15.                 'actions'=>array('admin','delete'),
  16.                 'users'=>array('@'),
  17.                                 'roles' => array('owner'),
  18.             ),
  19.             array('deny', // deny all users
  20.                 'users'=>array('*'),
  21.             ),
  22.         );
  23.     }

就是把刚刚建立的授权项目加入到访问控制列表中。

另外一个例子

  1. $auth = Yii::app()->authManger;
  2. $roleManager = $auth->createRole('manager'); //建立一个角色
  3. $auth->createTask('projectManager'); //建立任务
  4. $auth->createTask('userManager');
  5. $auth->createOpration('createProject'); //建立操作
  6. $auth->createOpration('updateProject');
  7. $auth->createOpration('deleteUser');
  8. $user = User::model()->findByPk('1'); //检索用户
  9. $roleManager->addChild('projectManager'); //为角色授权任务
  10. $roleManager->addChild('updateProject');//为角色授权操作
  11. $auth->assign('manager', $user->id);//指定用户权限
YII