继续摘抄:(ThinkPHP 1.5)基于RBAC的权限访问控制-实例解析

来源:互联网 发布:域名备案代理 编辑:程序博客网 时间:2024/05/17 22:18
(ThinkPHP 1.5)基于RBAC的权限访问控制-实例解析(
2009-11-27 09:02

常规的方式是通过设置

'USER_AUTH_ON'=>true,

来自动开启RBAC权限控制,这样的做法是会在App的初始化过程中进行权限认证和决策,但是有些情况下这样的设计并无法满足有些应用的特殊设计和定制需要。而我们可以用另外一种方式来手动进行认证判断,做法就是在一个公共的Action初始化方法里面进行权限认证判断。这种情况我们无需开启用户认证的开关,相当于和我们传统的权限控制模式有点类似。

 

下面要用到的基础知识:C方法用于快速获取和修改配置参数

 

public function _initialize() {

import('ORG.RBAC.RBAC');

// 检查认证

if(RBAC::checkAccess()) { //检查当前操作是否需要认证

//检查认证识别号

if(!$_SESSION[C('USER_AUTH_KEY')]) {

//如果session中没有以'USER_AUTH_KEY'为键值的数组,就跳转到认证网关

redirect(PHP_FILE.C('USER_AUTH_GATEWAY'));

}

// 检查权限

if(!RBAC::AccessDecision()) {

$this->error('没有权限!');

}

}

parent::_initialize();//此句导致任何地址都会跳转到本函数

}

在没有登录的情况下输入任何地址都会跳转到我们设置的认证网关,也就是Public模块的login操作。

 

登录后提交验证操作地址是/Public/CheckLogin,那么我们可以在Public模块的checkLogin操作方法中采用如下方式进行认证:

 

<?php

// 生成认证Map条件

// 这里使用用户名、密码和状态的方式进行认证

$map = array();

$map["account"] = $_POST['name'];

$map["password"] = $_POST['password'];

$map["status"] = 1;

// 进行委托认证

$authInfo = RBAC::authenticate($map); //默认使用User表来验证

if(false === $authInfo)

{

$this->error('登录失败,请检查用户名和密码是否有误!');

}

else

{

// 设置认证识别号

$_SESSION[C('USER_AUTH_KEY')] = $authInfo['id']; //写入session

//获取并保存用户访问权限列表

RBAC::saveAccessList();

// 登录成功,页面跳转

$this->success('登录成功!');

}

?>

 

这段代码或许是我们唯一需要在Action里面手动添加的代码,剩下的权限认证工作都由框架来自动完成。其实在这个例子里面,因为我们使用的是数据库方式的认证,所以看起来我们不使用

$authInfo = RBAC::authenticate($map);

一样也可以通过数据库的查询来进行登录检查,那为什么要使用RBAC::authenticate方法进行统一认证呢?原因很简单,当我们要使用其他委托认证方式的时候,可以无需修改代码,而直接修改配置文件就可以了。

这里的authenticate默认是使用User模型进行认证,如果你的模型不是UserModel而是MemberModel,那么需要修改为:

// 进行委托认证

$authInfo = RBAC::authenticate($map,'Member');

这里的Member并不是指数据表名称,而是你的模型名称,不要混淆了。

在这里系统对超级管理员的身份做了判断:

if($authInfo['account']=='admin') {

// 管理员不受权限控制影响

$_SESSION['administrator'] = true;

}

所以,当我们使用admin帐号登录的时候,就绕过了权限认证,因此可以进行所有的操作。这样做的目的,也是为了防止我们在授权错误后,仍然可以进入系统。

我们首先要在节点管理里面添加需要进行权限管理的项目、模块和操作节点。只有定义的节点才能进行授权,并且默认情况下,如果访问了一个没有定义的模块或者操作,会认为是没有权限。我们按照顺序在节点管理里面分别添加项目、模块和操作,并且我们把一些公共的操作定义到了Public模块里面,这个和我们后面的授权也有关系。

操作步骤:

首先:定义项目节点,这里我们要用项目的名称,这个例子的项目名称是RbacAdmin。

 

其次:从项目节点点击进入后,添加项目所属的模块节点(节点就是Action类)

例如:

数据管理 对应 FormAction

用户管理 对应 UserAction

权限管理 对应 GroupAction

节点管理 对应 NodeAction

默认模块 对应 IndexAction

公共模块 对应 PublicAction

注意名称要要类名一致,否则权限控制就不会起作用。

 

 

为了授权的简单起见,我们就把所有的操作放到Public模块里面定义,如果你不需要对各个模块的相同操作分别授权的话,这是一种方便的方法,否则你可能需要在各个模块下面都重复定义类似新增和插入的操作。下面是我们在后台管理要用到的操作方法,我们全部定义在Public模块下面:

添加完所有的节点后,我们就需要对用户组进行权限的授权了,我们选择权限管理,在里面添加了两个权限组:管理员组和普通用户组。

 

然后选择右边的操作区域的授权,进行组的授权,和添加节点的顺序一样,分别完成对项目、模块和操作的授权。

 

对项目授权

 

对项目下面的模块授权

 

对模块的操作授权

用户组的权限授权完成后,我们就需要把相关的用户放到某个组里面,让这些用户真正具有一定的权限。在权限组的列表中,我们选择操作区域的用户列表进入。

 

如果把某个用户加入了多个不同的组,那么他就会叠加所有组的权限。

我们对三个用户设置了不同的权限,分别是:

 

admin 超级管理员权限:可以访问所有操作

leader 管理员组:可以访问默认模块、公共模块、用户管理和数据管理,并且具有这些模块的所有的操作权限。

test 普通用户组:只能访问默认模块、公共模块和数据管理,并且只有列表、增加和编辑三个操作的权限。

 

下面我们就来实际看下ThinkPHP的RBAC权限控制的效果,我们分别用三种不同身份登录后可以看到的不同的菜单导航:

 

超级管理员的管理菜单

 

管理员组的管理菜单

 

普通用户组的管理菜单

关于动态菜单的控制,可以参考上面的相关代码,其实是把我们在节点管理中授权的模块根据用户权限的不同动态显示出来而已。

如果某个用户同时具有两个组的权限,那么就可以看到两个组的管理菜单。

假设我们用leader帐号登录,但是却想输入节点管理的操作URL地址来试图绕过权限直接访问

http://localhost/rbacadmin/index.php/Node/

由于节点管理和权限管理这两个模块并没有授权给管理员组,所以leader帐号当然也就没有这个模块的操作权限,因此会提示下面的错误页面:

 

同样,当我们用test帐号登录,并且对数据管理中的数据进行禁用操作的时候,也会提示没有权限,因为我们并没有给普通用户组授予禁用操作的权限。

 

 

示例中涉及到RBAC认证的代码并不多,大部分工作都由系统的RBAC类库来完成了。通常在最简单的模式下,我们只需要开启用户认证,并在用户认证的提交方法里面添加委托认证方法和获取权限列表信息就行了。这样,一个完善的用户权限控制体系就完成了。示例中的大部分代码都是用于权限的授权,这部分代码就不详细解析了,主要都是一些数据的存取操作和模板显示,更加详细的请参考示例中心的代码实例。

原创粉丝点击