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 ;
}
}
}
?>