Yii中srbac权限扩展模块工作原理与用法分析


Posted in PHP onJuly 14, 2016

本文实例讲述了Yii中srbac权限扩展模块工作原理与用法。分享给大家供大家参考,具体如下:

1. 设置权限规则表:可放在module模块配置文件里面

public function init() {
  //操作权限表,必须存在以下字段:
  //itemname角色名/ID,
  //type授权项目类型/1(任务)或者2(角色),
  //bizrule权限/逻辑运算表达式为false是有权限操作,
  //data数据/YII暂无利用
  Yii::app()->authManager->itemTable = 'AuthItem';
  //会员组-权限对应表,必须存在以下字段:
  //child子角色/ID,
  //parent父角色/ID,此表可循环执行,可多级继承
  Yii::app()->authManager->itemChildTable = 'uthItemChild';
  //会员-会员组对应表,会员组可直接为操作名称,必须存在以下字段:
  //itemname角色名/ID,
  //userid用户名/ID,
  //bizrule权限/逻辑运算表达式为false是有权限操作,
  //data数据/YII暂无利用
  Yii::app()->authManager->assignmentTable = 'zd_mem_glog';

2. 实现规则,所在控制器继承基类SBaseController,原来为Controller

class ProductController extends SBaseController
{
    ........
}
class SBaseController extends Controller
{
    ........
}

3. SBaseController继承基类Controller,前填加beforeAction,实现权限验证。

protected function beforeAction($action) {
  //载入模块分隔符
 $del = Helper::findModule('srbac')->delimeter;
 //取得前模块名称
 $mod = $this->module !== null ? $this->module->id . $del : "";
 $contrArr = explode("/", $this->id);
 $contrArr[sizeof($contrArr) - 1] = ucfirst($contrArr[sizeof($contrArr) - 1]);
 $controller = implode(".", $contrArr);
 $controller = str_replace("/", ".", $this->id);
 // 生成静态页面 模块+分隔符+控制器(首字母大写)+方法(首字母大写)例: model-ControllerAction
 if(sizeof($contrArr)==1){
  $controller = ucfirst($controller);
 }
 $access = $mod . $controller . ucfirst($this->action->id);
 //验证访问页面地址是否在总是允许列表里面,是返回有权限
 if (in_array($access, $this->allowedAccess())) {
  return true;
 }
 //验证SRBAC有无安装,没在安装,返回的权限访问
 if (!Yii::app()->getModule('srbac')->isInstalled()) {
  return true;
 }
 //验证SRBAC有无开启,没在开启,返回的权限访问
 if (Yii::app()->getModule('srbac')->debug) {
  return true;
 }
  // 权限验证
 if (!Yii::app()->user->checkAccess($access) || Yii::app()->user->isGuest) {
  $this->onUnauthorizedAccess();
 } else {
  return true;
 }
}

4. CDbAuthManager读取当前用户角色

public function getAuthAssignments($userId)
{
  $rows=$this->db->createCommand()
    ->select()
    ->from($this->assignmentTable)
    ->where('userid=:userid', array(':userid'=>$userId))
    ->queryAll();
  $assignments=array();
  foreach($rows as $row)
  {
    if(($data=@unserialize($row['data']))===false)
      $data=null;
    $assignments[$row['itemname']]=new CAuthAssignment($this,$row['itemname'],$row['userid'],$row['bizrule'],$data);
  }
  return $assignments;
}

5. CDbAuthManager读取角色对应权限

public function getAuthItem($name)
{
  $row=$this->db->createCommand()
    ->select()
    ->from($this->itemTable)
    ->where('name=:name', array(':name'=>$name))
    ->queryRow();
  if($row!==false)
  {
    if(($data=@unserialize($row['data']))===false)
      $data=null;
    return new CAuthItem($this,$row['name'],$row['type'],$row['description'],$row['bizrule'],$data);
  }
  else
    return null;
}

6. CDbAuthManager读取权限对应操作

protected function checkAccessRecursive($itemName,$userId,$params,$assignments)
{
  if(($item=$this->getAuthItem($itemName))===null)
    return false;
  Yii::trace('Checking permission "'.$item->getName().'"','system.web.auth.CDbAuthManager');
  if(!isset($params['userId']))
    $params['userId'] = $userId;
  if($this->executeBizRule($item->getBizRule(),$params,$item->getData()))
  {
    if(in_array($itemName,$this->defaultRoles))
      return true;
    if(isset($assignments[$itemName]))
    {
      $assignment=$assignments[$itemName];
      if($this->executeBizRule($assignment->getBizRule(),$params,$assignment->getData()))
        return true;
    }
    $parents=$this->db->createCommand()
      ->select('parent')
      ->from($this->itemChildTable)
      ->where('child=:name', array(':name'=>$itemName))
      ->queryColumn();
    foreach($parents as $parent)
    {
      if($this->checkAccessRecursive($parent,$userId,$params,$assignments))
        return true;
    }
  }
  return false;
}

7. CAuthManager验证权限

public function executeBizRule($bizRule,$params,$data)
{
  return $bizRule==='' || $bizRule===null || ($this->showErrors ? eval($bizRule)!=0 : @eval($bizRule)!=0);
}

8. 总是充许访问规则设置

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

PHP 相关文章推荐
用PHP实现小写金额转换大写金额的代码(精确到分)
Jan 10 PHP
基于PHP生成静态页的实现方法
May 10 PHP
php+highchats生成动态统计图
May 21 PHP
解密ThinkPHP3.1.2版本之模块和操作映射
Jun 19 PHP
用PHP解决的一个栈的面试题
Jul 02 PHP
PHP自带ZIP压缩、解压缩类ZipArchiv使用指南
Mar 03 PHP
PHP生成器简单实例
May 13 PHP
php rsa 加密,解密,签名,验签详解
Dec 06 PHP
PHP静态延迟绑定和普通静态效率的对比
Oct 20 PHP
PHP简单实现防止SQL注入的方法
Mar 13 PHP
实例讲解php实现多线程
Jan 27 PHP
PHP优化之批量操作MySQL实例分析
Apr 23 PHP
Yii视图操作之自定义分页实现方法
Jul 14 #PHP
全面解析PHP操作Memcache基本函数
Jul 14 #PHP
Yii视图CGridView实现操作按钮定义地址示例
Jul 14 #PHP
Yii中的relations数据关联查询及统计功能用法详解
Jul 14 #PHP
Yii基于CActiveForm的Ajax数据验证用法示例
Jul 14 #PHP
Yii实现Command任务处理的方法详解
Jul 14 #PHP
Yii使用DeleteAll连表删除出现报错问题的解决方法
Jul 14 #PHP
You might like
PHP中利用substr_replace将指定两位置之间的字符替换为*号
2011/01/27 PHP
php获取远程图片并下载保存到本地的方法分析
2016/10/08 PHP
Javascript中暂停功能的实现代码
2007/03/04 Javascript
select 控制网页内容隐藏于显示的实现代码
2010/05/25 Javascript
jQuery源码分析之Event事件分析
2010/06/07 Javascript
js插件YprogressBar实现漂亮的进度条效果
2015/04/20 Javascript
简介JavaScript中的getSeconds()方法的使用
2015/06/10 Javascript
解决jquery中动态新增的元素节点无法触发事件问题的两种方法
2015/10/30 Javascript
本地Bootstrap文件字体图标引入却无法显示问题的解决方法
2020/04/18 Javascript
JS实现数组去重复值的方法示例
2017/02/18 Javascript
Node.js websocket使用socket.io库实现实时聊天室
2017/02/20 Javascript
详解vue beforeRouteEnter 异步获取数据给实例问题
2019/08/09 Javascript
[00:57]深扒TI7聊天轮盘语音出处5
2017/05/11 DOTA
Python pass详细介绍及实例代码
2016/11/24 Python
python merge、concat合并数据集的实例讲解
2018/04/12 Python
python之super的使用小结
2018/08/13 Python
python语音识别指南终极版(有这一篇足矣)
2020/09/09 Python
利用python查看数组中的所有元素是否相同
2021/01/08 Python
使用CSS3编写类似iOS中的复选框及带开关的按钮
2016/04/11 HTML / CSS
HTML5页面嵌入小程序没有返回按钮及返回页面空白的问题
2020/05/28 HTML / CSS
企划经理的岗位职责
2013/11/17 职场文书
高一地理教学反思
2014/01/18 职场文书
建筑安全员岗位职责
2014/03/13 职场文书
书法兴趣小组活动总结
2014/07/07 职场文书
药店促销活动策划方案
2014/08/24 职场文书
幼儿教师自我剖析材料
2014/09/29 职场文书
自主招生推荐信怎么写
2015/03/26 职场文书
财务出纳岗位职责
2015/03/31 职场文书
六一儿童节园长致辞
2015/07/31 职场文书
红领巾广播站广播稿
2015/08/19 职场文书
创业计划书之花店
2019/09/20 职场文书
PHP实现创建以太坊钱包转账等功能
2021/04/21 PHP
Mysql数据库命令大全
2021/05/26 MySQL
详解 TypeScript 枚举类型
2021/11/02 Javascript
详解Python内置模块Collections
2022/03/22 Python
redis 解决库存并发问题实现数量控制
2022/04/08 Redis