好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

PHPACL角色权限控制

 

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

代码如下

<?php

class Acl {

    /**

     * 默认权限检查的处理程序设置,可以是函数名或是数组(array(类名,方法)的形式)

     */

    public $checker = array ( 'spAclModel' , 'check' ) ;

 

    /**

     * 默认提示无权限提示,可以是函数名或是数组(array(类名,方法)的形式)

     */

    public $prompt = array ( 'spAcl' , 'def_prompt' ) ;

    /**

     * 构造函数,设置权限检查程序与提示程序

     */

    public function __construct ( ) {

        $params = spExt ( "spAcl" ) ;

        if ( ! empty ( $params [ "prompt" ] ) ) $this -> prompt = $params [ "prompt" ] ;

        if ( ! empty ( $params [ "checker" ] ) ) $this -> checker = $params [ "checker" ] ;

    }

 

    /**

     * 获取当前会话的用户标识

     */

    public function get ( ) {

        return $_SESSION [ "SpAclSession" ] ;

    }

 

    /**

     * 强制控制的检查程序,适用于后台。无权限控制的页面均不能进入

     */

    public function maxcheck ( ) {

        $acl_handle = $this -> check ( ) ;

        if ( 1 !== $acl_handle ) {

            $this -> prompt ( ) ;

            return FALSE ;

        }

        return TRUE ;

    }

 

    /**

     * 有限的权限控制,适用于前台。仅在权限表声明禁止的页面起作用,其他无声明页面均可进入

     */

    public function mincheck ( ) {

        $acl_handle = $this -> check ( ) ;

        if ( 0 === $acl_handle ) {

            $this -> prompt ( ) ;

            return FALSE ;

        }

        return TRUE ;

    }

 

    /**

     * 使用程序调度器进行检查等处理

     */

    private function check ( ) {

        GLOBAL $__controller , $__action ;

        $checker = $this -> checker ; $name = $this -> get ( ) ;

 

        if ( is_array ( $checker ) ) {

            return spClass ( $checker [ 0 ] ) -> { $checker [ 1 ] } ( $name , $__controller , $__action ) ;

        } else {

            return call_user_func_array ( $checker , array ( $name , $__controller , $__action ) ) ;

        }

    }

    /**

     * 无权限提示跳转

     */

    public function prompt ( ) {

        $prompt = $this -> prompt ;

        if ( is_array ( $prompt ) ) {

            return spClass ( $prompt [ 0 ] ) -> { $prompt [ 1 ] } ( ) ;

        } else {

            return call_user_func_array ( $prompt , array ( ) ) ;

        }

    }

 

    /**

     * 默认的无权限提示跳转

     */

    public function def_prompt ( ) {

        $url = spUrl ( ) ; // 跳转到首页,在强制权限的情况下,请将该页面设置成可以进入。

        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>" ;

        exit ;

    }

 

    /**

     * 设置当前用户,内部使用SESSION记录

     *

     * @param acl_name    用户标识:可以是组名或用户名

     */

    public function set ( $acl_name ) {

        $_SESSION [ "SpAclSession" ] = $acl_name ;

    }

 

    /**

     * 获取安全加密的密码输入框,开发者将需要在HTML中form标签上加入<code>onsubmit="aclcode();"</code>来触发加密

     *

     * @param id    在input框的id值。

     * @param add    在input框内的其他内容,除id外,name,class等均可。

     */

    public function pwinput ( $id , $add = null ) {

        $raphash = substr ( md5 ( mt_rand ( 10000 , 99999 ) ) , 2 , 12 ) ;

        $html = "<script type='text/javascript'>" . spAcl :: getmd5 ( ) . "</script>" ;

        $html .= "<script type='text/javascript'>function aclcode(){aclpwinput=document.getElementById(' {$id} ');document.getElementById(' {$raphash} ').value = hex_md5(aclpwinput.value);aclpwinput.value = '0000000000000000';}</script>" ;

        $html .= "<input type='password' id=' {$id} ' {$add} >" ;

        $html .= "<input type='hidden' id=' {$raphash} ' name=' {$raphash} '>" ;

        $_SESSION [ "SpAclInputHash" ] = $raphash ;

        return $html ;

    }

    /**

     * 辅助pwinput的函数,让pwinput可在模板中使用。

     * @param params 传入的参数

     */

    public function smarty_pwinput ( $params ) {

        return spAcl :: pwinput ( $params [ "id" ] , $params [ "add" ] ) ;

    }

    /**

     * 获取加密后的密码,该密码为MD5加密后的字符串

     *

     * 请注意返回值:

     *

     * -1 是无hash值,可以判断为远程提交等方式的攻击或是访问超时。需要重新访问登录页面。

     * false 是没有输入密码,或是远程提交导致无法获取到正确的hash码。同样要求重新访问登录页面以再次输入密码提交。

     * MD5编码后的密码

     */

    public function pwvalue ( )

    {

        if ( empty ( $_SESSION [ "SpAclInputHash" ] ) ) return - 1 ;

        $md5pw = spClass ( "spArgs" ) -> get ( $_SESSION [ "SpAclInputHash" ] , false ) ;

        unset ( $_SESSION [ "SpAclInputHash" ] ) ;

        return $md5pw ;

    }

 

}

 

class spAclModel extends spModel {

 

    public $pk = 'aclid' ;

    /**

     * 表名

     */

    public $table = 'acl' ;

 

    /**

     * 检查对应的权限

     *

     * 返回1是通过检查,0是不能通过检查(控制器及动作存在但用户标识没有记录)

     * 返回-1是无该权限控制(即该控制器及动作不存在于权限表中)

     *

     * @param acl_name    用户标识:可以是组名或是用户名

     * @param controller    控制器名称

     * @param action    动作名称

     */

    public function check ( $acl_name = SPANONYMOUS , $controller , $action ) {

        $rows = array ( 'controller' => $controller , 'action' => $action ) ;

        if ( $acl = $this -> findAll ( $rows ) ) {

            foreach ( $acl as $v ) {

                if ( $v [ "acl_name" ] == SPANONYMOUS || $v [ "acl_name" ] == $acl_name ) return 1 ;

            }

            return 0 ;

        } else {

            return - 1 ;

        }

    }

}

?>

 

查看更多关于PHPACL角色权限控制的详细内容...

  阅读:42次