php ci框架使用qeephp框架的acl实现权限验证
2013-03-20 16:30
776 查看
1、在libraries文件夹下添加Acl.php类库
View Code
2、在项目文件夹下的core文件夹中创建核心类MY_Controller.php,在该文件中添加权限验证,所有需要验证的控制器文件都要继承该类。
3、权限配置文件,在项目的config文件夹下添加acl.php文件,格式参考下面的示例代码。
该文件中配置了testacl控制器的访问权限为ACL_HAS_ROLE,即所有拥有角色的用户都有权限访问。
actions中配置的是testacl控制器中index方法和add方法的访问权限。“allow”表示可以访问的角色,“deny”表示不允许访问的角色。
Acl中预定义的角色常量如下:
ACL_EVERYONE = 'acl_everyone'; // 所有用户
ACL_NULL = 'acl_null'; // 未设置
ACL_NO_ROLE = 'acl_no_role'; // 没有角色用户
ACL_HAS_ROLE = 'acl_has_role'; // 有角色用户
ALL_CONTROLLERS = 'all_controllers'; // 表示所有控制器
ALL_ACTIONS = 'all_actions'; // 表示所有控制器内的方法
4、测试一下,创建一个testacl.php文件,
运行结果:在MY_Controller中我们假设了role=“gm”,
所以访问http://localhost/CodeIgniter_2.1.1/index.php?c=testacl&m=index时输出 "index method"
而访问:http://localhost/CodeIgniter_2.1.1/index.php?c=testacl&m=add时输出 “无权限”。
View Code
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * ACL 实现了权限检查服务 * * “基于角色”通过比对拥有的角色和访问需要的角色来决定是否通过权限检查。 * * 在进行权限检查时,要求分别提供角色组和访问控制列表(ACL)。 * 然后由 QACL 比对角色组和 ACL,并返回检查结果。 * * rolesBasedCheck() 用于比对权限,并返回结果。 * role_normalize() 方法用于将 roles 角色配置 转换为符合规范的 数组形式。 * acl_normalize() 方法用于将 ACL 转换为符合规范的 ACL。 */ class Acl { /** * 预定义角色常量 */ const ACL_EVERYONE = 'acl_everyone'; const ACL_NULL = 'acl_null'; const ACL_NO_ROLE = 'acl_no_role'; const ACL_HAS_ROLE = 'acl_has_role'; const ALL_CONTROLLERS = 'all_controllers'; const ALL_ACTIONS = 'all_actions'; var $uri = array('space'=>'','controller'=>'','action'=>''); var $acl; var $acl_controller; var $acl_action; var $roles; function __construct(){ if(function_exists('get_instance') && class_exists('CI_Controller')){ $CI =& get_instance(); $this->uri = array( 'space' => $CI->router->fetch_directory(), 'controller' => $CI->router->fetch_class(), 'action' => $CI->router->fetch_method() ); } } /** * 对 roles 进行权限验证 * @param array $roles * @param array $acl_uri space空间命名(CI中的controllers/下dir分目录) controller控制器文件 action为控制器处理函数 * @param array $acl 自定义权限验证配置 * @return array */ function checkAcl($roles, $uri = array(),$acl = array()){ if(!empty($uri)) $this->uri = array_merge($this->uri,$uri); $acl_file = 'acl'; if(isset($this->uri['space'])){ if(!empty($this->uri['space'])){ $acl_file .= '_'.$this->uri['space']; } } if(empty($acl)){ $filepath = APPPATH.'config/'.$acl_file.'.php'; if (!file_exists($filepath)) return TRUE; } $this->roles = $this->roles_normalize($roles); include($filepath); $this->acl = $acl; $this->acl_controller = $this->_controllerACL($this->uri['controller']); return $this->_actionACL($this->uri['action']); } /** * 对 roles 整理,返回整理结果 * @param array $roles * @return array */ function roles_normalize($roles){ if (!is_array($roles)){ $roles = explode(',', $roles); } return array_map('strtolower',array_filter(array_map('trim',$roles),'strlen')); } /** * 对 ACL 整理,返回整理结果 * @param array $acl 要整理的 ACL * @return array */ function acl_normalize(array $acl){ $acl = array_change_key_case($acl, CASE_LOWER); $ret = array(); $keys = array('allow', 'deny'); foreach ($keys as $key){ do{ if (!isset($acl[$key])){ $values = self::ACL_NULL; break; } $acl[$key] = strtolower($acl[$key]); if($acl[$key] == self::ACL_EVERYONE || $acl[$key] == self::ACL_HAS_ROLE || $acl[$key] == self::ACL_NO_ROLE || $acl[$key] == self::ACL_NULL){ $values = $acl[$key]; break; } $values = $this->roles_normalize($acl[$key]); if (empty($values)){ $values = self::ACL_NULL; } }while (FALSE); $ret[$key] = $values; } return $ret; } /** * 对 controller 访问控制做处理 * @param string $controller * @return array */ protected function _controllerACL($controller){ if(isset($this->acl[$controller])){ $this->acl = array_change_key_case($this->acl, CASE_LOWER); return (array)$this->acl[$controller]; } return isset($this->acl[self::ALL_CONTROLLERS]) ? (array)$this->acl[self::ALL_CONTROLLERS] : array('allow' => self::ACL_EVERYONE); } /** * 对 action 访问控制做处理 * @param string $action * @return array */ protected function _actionACL($action){ if(isset($this->acl_controller['actions'][$action])){ return $this->_rolesBasedCheck($this->acl_controller['actions'][$action]); } if(isset($this->acl_controller['actions'][self::ALL_ACTIONS])){ return $this->_rolesBasedCheck($this->acl_controller['actions'][self::ALL_ACTIONS]); } if(isset($this->acl_controller)){ return $this->_rolesBasedCheck($this->acl_controller); } } /** * 进行实际权限校验 * @param string $acl * @return array */ protected function _rolesBasedCheck($acl){ $this->acl_action = $this->acl_normalize($acl); if ($this->acl_action['allow'] == self::ACL_EVERYONE){ // 如果 allow 允许所有角色,deny 没有设置,则检查通过 if ($this->acl_action['deny'] == self::ACL_NULL){ return TRUE; } // 如果 deny 为 acl_no_role,则只要用户具有角色就检查通过 if ($this->acl_action['deny'] == self::ACL_NO_ROLE){ if (empty($this->roles)){ return FALSE; } return TRUE; } // 如果 deny 为 acl_has_role,则只有用户没有角色信息时才检查通过 if ($this->acl_action['deny'] == self::ACL_HAS_ROLE){ if (empty($this->roles)){ return TRUE; } return FALSE; } // 如果 deny 也为 acl_everyone,则表示 acl 出现了冲突 if ($this->acl_action['deny'] == self::ACL_EVERYONE){ return FALSE; } // 只有 deny 中没有用户的角色信息,则检查通过 foreach ($this->roles as $role){ if (in_array($role, $this->acl_action['deny'])){ return FALSE; } } return TRUE; } do{ // 如果 allow 要求用户具有角色,但用户没有角色时直接不通过检查 if ($this->acl_action['allow'] == self::ACL_HAS_ROLE){ if (!empty($this->roles)){ break; } return FALSE; } // 如果 allow 要求用户没有角色,但用户有角色时直接不通过检查 if ($this->acl_action['allow'] == self::ACL_NO_ROLE){ if (empty($this->roles)){ break; } return FALSE; } if ($this->acl_action['allow'] != self::ACL_NULL){ // 如果 allow 要求用户具有特定角色,则进行检查 $passed = FALSE; foreach ($this->roles as $role){ if (in_array($role, $this->acl_action['allow'])){ $passed = TRUE; break; } } if (!$passed){ return FALSE; } } } while (FALSE); // 如果 deny 没有设置,则检查通过 if ($this->acl_action['deny'] == self::ACL_NULL){ return TRUE; } // 如果 deny 为 acl_no_role,则只要用户具有角色就检查通过 if ($this->acl_action['deny'] == self::ACL_NO_ROLE){ if (empty($this->roles)){ return FALSE; } return TRUE; } // 如果 deny 为 acl_has_role,则只有用户没有角色信息时才检查通过 if ($this->acl_action['deny'] == self::ACL_HAS_ROLE){ if (empty($this->roles)){ return TRUE; } return FALSE; } // 如果 deny 为 acl_everyone,则检查失败 if ($this->acl_action['deny'] == self::ACL_EVERYONE){ return FALSE; } // 只有 deny 中没有用户的角色信息,则检查通过 foreach ($this->roles as $role){ if (in_array($role, $this->acl_action['deny'])){ return FALSE; } } return TRUE; } } // END Controller class /* End of file Acl.php */ /* Location: ./application/libraries/Acl.php */
2、在项目文件夹下的core文件夹中创建核心类MY_Controller.php,在该文件中添加权限验证,所有需要验证的控制器文件都要继承该类。
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Auth_Controller extends CI_Controller { var $role = ''; var $uid = 0; var $username = ''; var $_ckey=''; var $_akey=''; var $_mkey=''; function __construct() { parent::__construct(); //引入Acl类库 $this->load->library(array('Acl','common')); //假设现在角色为admin,这里可以自已定义获取角色权限的方法。 $this->role = 'gm'; //执行权限判断 if(!$this->acl->checkAcl( $this->role )){ if( method_exists($this,'_on_access_denied') ) $this->_on_access_denied(); } } /* * @name _on_access_denied 访问无权限时处理方法 * @return null */ protected function _on_access_denied() { header('Content-type: text/html; charset=utf-8'); echo '无权限';exit; // header('Location: '.config_item('sso_admin_url').'?ref='.urlencode(config_item('ref_url')));exit; } protected function _db_error(){ echo 'DB_error();';exit; } protected function _redirectMessage($heading,$message,$url,$time=5,$hidden_script='') { $this->load->view('common/show_msg',array('message_caption'=>$heading,'message_body'=>$message,'redirect_url'=>$url,'redirect_delay'=>$time,'hidden_script'=>$hidden_script)); return; } protected function _FailMessage($info,$msg,$url = array()){ if(is_array($url)) $url = $this->common->Get_Url($url); return $this->_redirectMessage($this->common->Get_ErrorMsg($info),$this->common->Get_ErrorMsg($msg),$url); } } // END Controller class /* End of file Auth_Controller.php */ /* Location: ./application/libraries/Auth_Controller.php */
3、权限配置文件,在项目的config文件夹下添加acl.php文件,格式参考下面的示例代码。
该文件中配置了testacl控制器的访问权限为ACL_HAS_ROLE,即所有拥有角色的用户都有权限访问。
actions中配置的是testacl控制器中index方法和add方法的访问权限。“allow”表示可以访问的角色,“deny”表示不允许访问的角色。
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); //遵循qeephp中的acl规则 $acl['all_controllers'] = array( 'allow'=>'ACL_HAS_ROLE',//表示所有拥有角色的用户 ); $acl['testacl'] = array( 'allow'=>'ACL_HAS_ROLE', 'actions'=>array( 'index'=>array('allow' => 'admin,editor,gm'), 'add' => array('allow'=> 'admin,editor'), ), );
Acl中预定义的角色常量如下:
ACL_EVERYONE = 'acl_everyone'; // 所有用户
ACL_NULL = 'acl_null'; // 未设置
ACL_NO_ROLE = 'acl_no_role'; // 没有角色用户
ACL_HAS_ROLE = 'acl_has_role'; // 有角色用户
ALL_CONTROLLERS = 'all_controllers'; // 表示所有控制器
ALL_ACTIONS = 'all_actions'; // 表示所有控制器内的方法
4、测试一下,创建一个testacl.php文件,
<?php class Testacl extends Auth_Controller { function __construct() { parent::__construct(); } function index() { echo "index method"; } function add() { echo "添加页,只有管理员和编辑有权限操作"; } }
运行结果:在MY_Controller中我们假设了role=“gm”,
所以访问http://localhost/CodeIgniter_2.1.1/index.php?c=testacl&m=index时输出 "index method"
而访问:http://localhost/CodeIgniter_2.1.1/index.php?c=testacl&m=add时输出 “无权限”。
相关文章推荐
- PHP+TP框架实现获取微信JS-SDK使用权限签名算法需要的jsapi_ticket,并全局缓存
- 如何使用PHP中ci框架实现验证码?
- 使用php的ci框架,实现微信支付(jsapi方式+完整代码)
- 如何使用PHP中ci框架实现验证码?
- shiro框架---关于用户登录和权限验证功能的实现步骤(二)
- 使用php实现权限管理模块
- shiro框架---关于用户登录和权限验证功能的实现步骤(四)
- PHP之运用CI用钩子实现URL权限控制
- PHP CI框架中实现事物回滚
- 权限管理框架实现(2)--Struts中ValueStack使用
- JAX-WS使用Handler实现简单的WebService权限验证
- 基于权限安全框架Shiro的登录验证功能实现
- SpringMVC+Spring+mybatis 实现登录过程(使用后台验证框架)
- CI Codeigniter框架里面PHPExcel的使用|导出数据到Excel文件
- 简单两步快速实现shiro的配置和使用,包含登录验证、角色验证、权限验证以及shiro登录注销流程
- 【php】PHP中使用crypt()实现用户身份验证的代码
- 使用Yii框架做权限验证 -- 从无到企业级别控制
- PHP CI框架学习笔记-分页实现程序
- PHP 实现 注册等的邮箱验证 (二)—— 使用 PHPMailer 发送邮件
- 使用php的swoole框架,实现高性能长连接websocket