PHPACL角色权限控制

浏览量:773 | 分类:PHP | 发布日期:2010-05-23

PHP ACL角色权限类,能实现无限角色权限的访问控制
网上关于RBAC方面资料比较少!
原理很简单,就是在执行control 前检查controller和action在acl表中的权限,
判断当前的访问者“可以”或“不可以”访问某个action的机制
满足条件就继续执行,否则跳转的制定页面
 

代码如下
  1. <?php
  2. class Acl{
  3.     /**
  4.      * 默认权限检查的处理程序设置,可以是函数名或是数组(array(类名,方法)的形式)
  5.      */
  6.     public $checker = array('spAclModel','check');
  7.  
  8.     /**
  9.      * 默认提示无权限提示,可以是函数名或是数组(array(类名,方法)的形式)
  10.      */
  11.     public $prompt = array('spAcl','def_prompt');
  12.     /**
  13.      * 构造函数,设置权限检查程序与提示程序
  14.      */
  15.     public function __construct(){
  16.         $params = spExt("spAcl");
  17.         if( !empty($params["prompt"]) )$this->prompt = $params["prompt"];
  18.         if( !empty($params["checker"]) )$this->checker = $params["checker"];
  19.     }
  20.  
  21.     /**
  22.      * 获取当前会话的用户标识
  23.      */
  24.     public function get(){
  25.         return $_SESSION["SpAclSession"];
  26.     }
  27.  
  28.     /**
  29.      * 强制控制的检查程序,适用于后台。无权限控制的页面均不能进入
  30.      */
  31.     public function maxcheck(){
  32.         $acl_handle = $this->check();
  33.         if( 1 !== $acl_handle ){
  34.             $this->prompt();
  35.             return FALSE;
  36.         }
  37.         return TRUE;
  38.     }
  39.  
  40.     /**
  41.      * 有限的权限控制,适用于前台。仅在权限表声明禁止的页面起作用,其他无声明页面均可进入
  42.      */
  43.     public function mincheck(){
  44.         $acl_handle = $this->check();
  45.         if( 0 === $acl_handle ){
  46.             $this->prompt();
  47.             return FALSE;
  48.         }
  49.         return TRUE;
  50.     }
  51.  
  52.     /**
  53.      * 使用程序调度器进行检查等处理
  54.      */
  55.     private function check(){
  56.         GLOBAL $__controller, $__action;
  57.         $checker = $this->checker; $name = $this->get();
  58.  
  59.         if( is_array($checker) ){
  60.             return spClass($checker[0])->{$checker[1]}($name, $__controller, $__action);
  61.         }else{
  62.             return call_user_func_array($checker, array($name, $__controller, $__action));
  63.         }
  64.     }
  65.     /**
  66.      * 无权限提示跳转
  67.      */
  68.     public function prompt(){
  69.         $prompt = $this->prompt;
  70.         if( is_array($prompt) ){
  71.             return spClass($prompt[0])->{$prompt[1]}();
  72.         }else{
  73.             return call_user_func_array($prompt,array());
  74.         }
  75.     }
  76.  
  77.     /**
  78.      * 默认的无权限提示跳转
  79.      */
  80.     public function def_prompt(){
  81.         $url = spUrl(); // 跳转到首页,在强制权限的情况下,请将该页面设置成可以进入。
  82.         echo "<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><script>function sptips(){alert("Access Failed!");location.href="{$url}";}</script></head><body onload="sptips()"></body></html>";
  83.         exit;
  84.     }
  85.  
  86.     /**
  87.      * 设置当前用户,内部使用SESSION记录
  88.      *
  89.      * @param acl_name    用户标识:可以是组名或用户名
  90.      */
  91.     public function set($acl_name){
  92.         $_SESSION["SpAclSession"] = $acl_name;
  93.     }
  94.  
  95.     /**
  96.      * 获取安全加密的密码输入框,开发者将需要在HTML中form标签上加入<code>onsubmit="aclcode();"</code>来触发加密
  97.      *
  98.      * @param id    在input框的id值。
  99.      * @param add    在input框内的其他内容,除id外,name,class等均可。
  100.      */
  101.     public function pwinput($id, $add = null){
  102.         $raphash = substr(md5(mt_rand(10000,99999)),2,12);
  103.         $html = "<script type='text/javascript'>".spAcl::getmd5()."</script>";
  104.         $html .= "<script type='text/javascript'>function aclcode(){aclpwinput=document.getElementById('{$id}');document.getElementById('{$raphash}').value = hex_md5(aclpwinput.value);aclpwinput.value = '0000000000000000';}</script>";
  105.         $html .= "<input type='password' id='{$id}' {$add}>";
  106.         $html .= "<input type='hidden' id='{$raphash}' name='{$raphash}'>";
  107.         $_SESSION["SpAclInputHash"] = $raphash;
  108.         return $html;
  109.     }
  110.     /**
  111.      * 辅助pwinput的函数,让pwinput可在模板中使用。
  112.      * @param params 传入的参数
  113.      */
  114.     public function smarty_pwinput($params){
  115.         return spAcl::pwinput($params["id"],$params["add"]);
  116.     }
  117.     /**
  118.      * 获取加密后的密码,该密码为MD5加密后的字符串
  119.      *
  120.      * 请注意返回值:
  121.      *
  122.      * -1 是无hash值,可以判断为远程提交等方式的攻击或是访问超时。需要重新访问登录页面。
  123.      * false 是没有输入密码,或是远程提交导致无法获取到正确的hash码。同样要求重新访问登录页面以再次输入密码提交。
  124.      * MD5编码后的密码
  125.      */
  126.     public function pwvalue()
  127.     {
  128.         if(empty($_SESSION["SpAclInputHash"]))return -1;
  129.         $md5pw = spClass("spArgs")->get($_SESSION["SpAclInputHash"],false);
  130.         unset($_SESSION["SpAclInputHash"]);
  131.         return $md5pw;
  132.     }
  133.  
  134. }
  135.  
  136. class spAclModel extends spModel{
  137.  
  138.     public $pk = 'aclid';
  139.     /**
  140.      * 表名
  141.      */
  142.     public $table = 'acl';
  143.  
  144.     /**
  145.      * 检查对应的权限
  146.      *
  147.      * 返回1是通过检查,0是不能通过检查(控制器及动作存在但用户标识没有记录)
  148.      * 返回-1是无该权限控制(即该控制器及动作不存在于权限表中)
  149.      *
  150.      * @param acl_name    用户标识:可以是组名或是用户名
  151.      * @param controller    控制器名称
  152.      * @param action    动作名称
  153.      */
  154.     public function check($acl_name = SPANONYMOUS, $controller, $action){
  155.         $rows = array('controller' => $controller, 'action' => $action );
  156.         if( $acl = $this->findAll($rows) ){
  157.             foreach($acl as $v){
  158.                 if($v["acl_name"] == SPANONYMOUS || $v["acl_name"] == $acl_name)return 1;
  159.             }
  160.             return 0;
  161.         }else{
  162.             return -1;
  163.         }
  164.     }
  165. }
  166. ?>

上一篇: PPC优秀版主

下一篇: 看看你能答对几个题

评论

过客易棋牌   2010-06-01 02:18:12

顶.....................

易棋牌   2010-06-05 04:04:58

不错哦````````````