CPhpAuthManager


system.web.auth
继承 class CPhpAuthManager » CAuthManager » CApplicationComponent » CComponent
实现 IAuthManager, IApplicationComponent
源自 1.0
版本 $Id: CPhpAuthManager.php 3515 2011-12-28 12:29:24Z mdomba $
源码
CPhpAuthManager代表授权信息存储在一个PHP文件的授权管理器。

授权数据在指定的文件authFile 里面保存/加载, 默认是’protected/data/auth.php‘。

CPhpAuthManager主要是应用在授权数据不多的情况下 (如,个人博客系统的授权信息)。 如果是比较复杂的授权数据,应该使用CDbAuthManager

公共属性

属性 类型 描述 定义在
authFile string 包含授权数据的PHP文件路径。 如果没有设置,它会使用‘protected/data/auth. CPhpAuthManager
authItems array 返回指定类型和用户的授权项目。 CPhpAuthManager
behaviors array 这个应用组件附加的行为。 这此行为将在应用组件调用init时附加在应用组件上。 请参照CModel::behaviors如何指定此属性值。 CApplicationComponent
defaultRoles array 隐式赋予给所有用户的角色名字列表。 这些角色不需要显式赋予给所有用户。 当调用checkAccess,会首先检查这些角色。 为了能够提高程序效率,这样的角色越少越好。 一个典型的用法是,定义一个“authenticated”角色,然后 把它关联到一个业务逻辑规则,这个规则是用来验证当前用户的。 然后在这个属性声明“authenticated”以便应用到 所有的验证用户。 CAuthManager
isInitialized boolean 检查应用组件是否已经初始化。 CApplicationComponent
operations array 返回操作。 CAuthManager
roles array 返回角色。 CAuthManager
showErrors boolean 允许业务规则错误报告。 CAuthManager
tasks array 返回任务。 CAuthManager

公共方法

方法 描述 定义在
__call() 如果类中没有调的方法名,则调用这个方法。 CComponent
__get() 返回一个属性值、一个事件处理程序列表或一个行为名称。 CComponent
__isset() 检查一个属性是否为null。 CComponent
__set() 设置一个组件的属性值。 CComponent
__unset() 设置一个组件的属性为null。 CComponent
addItemChild() 添加一个授权项目作为另一个授权项的子授权项目。 CPhpAuthManager
asa() 返回这个名字的行为对象。 CComponent
assign() 为用户分配一个授权项目。 CPhpAuthManager
attachBehavior() 附加一个行为到组件。 CComponent
attachBehaviors() 附加一个行为列表到组件。 CComponent
attachEventHandler() 为事件附加一个事件处理程序。 CComponent
canGetProperty() 确定属性是否可读。 CComponent
canSetProperty() 确定属性是否可写。 CComponent
checkAccess() 检查指定用户的执行权限。 CPhpAuthManager
clearAll() 移除所有授权数据。 CPhpAuthManager
clearAuthAssignments() 移除所有授权分配信息。 CPhpAuthManager
createAuthItem() 创建一个授权项目。 CPhpAuthManager
createOperation() 创建一个操作。 CAuthManager
createRole() 创建一个角色。 CAuthManager
createTask() 创建一个任务。 CAuthManager
detachBehavior() 从组件中分离一个行为。 CComponent
detachBehaviors() 从组件中分离所有行为。 CComponent
detachEventHandler() 分离一个存在的事件处理程序。 CComponent
disableBehavior() 禁用一个附加行为。 CComponent
disableBehaviors() 禁用组件附加的所有行为。 CComponent
enableBehavior() 启用一个附加行为。 CComponent
enableBehaviors() 启用组件附加的所有行为。 CComponent
evaluateExpression() 计算一个PHP表达式,或根据组件上下文执行回调。 CComponent
executeBizRule() 执行指定的业务规则。 CAuthManager
getAuthAssignment() 返回项目任务信息。 CPhpAuthManager
getAuthAssignments() 返回指定用户的项目任务。 CPhpAuthManager
getAuthItem() 返回指定名字的授权项目。 CPhpAuthManager
getAuthItems() 返回指定类型和用户的授权项目。 CPhpAuthManager
getEventHandlers() 返回一个事件的附加处理程序列表。 CComponent
getIsInitialized() 检查应用组件是否已经初始化。 CApplicationComponent
getItemChildren() 返回指定项目的子项目 CPhpAuthManager
getOperations() 返回操作。 CAuthManager
getRoles() 返回角色。 CAuthManager
getTasks() 返回任务。 CAuthManager
hasEvent() 确定一个事件是否定义。 CComponent
hasEventHandler() 检查事件是否有附加的处理程序。 CComponent
hasItemChild() 返回值说明父授权项目是否包含子授权项目。 CPhpAuthManager
hasProperty() 确定属性是否被定义。 CComponent
init() 初始化应用组件。 CPhpAuthManager
isAssigned() 返回值说明这个项目是否已经赋予给用户。 CPhpAuthManager
load() 加载授权数据。 CPhpAuthManager
raiseEvent() 发起一个事件。 CComponent
removeAuthItem() 移除指定的授权项目。 CPhpAuthManager
removeItemChild() 移除子项目。 CPhpAuthManager
revoke() 撤消用户的授权任务。 CPhpAuthManager
save() 将授权数据保存到持久化存储器。 CPhpAuthManager
saveAuthAssignment() 保存修改的授权信息。 CPhpAuthManager
saveAuthItem() 将授权项目保存到持久化存储器。 CPhpAuthManager

受保护方法

方法 描述 定义在
checkItemChildType() 检查项目类型以确定一个子项目已经赋予给一个父项目。 CAuthManager
detectLoop() 检查授权项目层级是否存在循环。 CPhpAuthManager
loadFromFile() 从PHP文件加载授权数据。 CPhpAuthManager
saveToFile() 保存授权数据到PHP文件。 CPhpAuthManager

属性详细

authFile 属性
public string $authFile;

包含授权数据的PHP文件路径。 如果没有设置,它会使用‘protected/data/auth.php’作为数据文件。 如果需要修改授权数据,要确保网络服务进程对该文件 有写的权限。

authItems 属性 只读
public array getAuthItems(integer $type=NULL, mixed $userId=NULL)

返回指定类型和用户的授权项目。

方法详细

addItemChild() 方法
public boolean addItemChild(string $itemName, string $childName)
$itemName string 父项目名字
$childName string 子项目名字
{return} boolean 是否添加成功
public function addItemChild($itemName,$childName)
{
    if(!isset(
$this->_items[$childName],$this->_items[$itemName]))
        throw new 
CException(Yii::t('yii','Either "{parent}" or "{child}" does not exist.',array('{child}'=>$childName,'{name}'=>$itemName)));
    
$child=$this->_items[$childName];
    
$item=$this->_items[$itemName];
    
$this->checkItemChildType($item->getType(),$child->getType());
    if(
$this->detectLoop($itemName,$childName))
        throw new 
CException(Yii::t('yii','Cannot add "{child}" as a child of "{parent}". A loop has been detected.',
            array(
'{child}'=>$childName,'{parent}'=>$itemName)));
    if(isset(
$this->_children[$itemName][$childName]))
        throw new 
CException(Yii::t('yii','The item "{parent}" already has a child "{child}".',
            array(
'{child}'=>$childName,'{parent}'=>$itemName)));
    
$this->_children[$itemName][$childName]=$this->_items[$childName];
    return 
true;
}

添加一个授权项目作为另一个授权项的子授权项目。

assign() 方法
public CAuthAssignment assign(string $itemName, mixed $userId, string $bizRule=NULL, mixed $data=NULL)
$itemName string 项目名字
$userId mixed 用户ID(详情请参考IWebUser::getId
$bizRule string 当调用checkAccess时, 具体的授权项目的业务规则。
$data mixed 这个任务额外的数据。
{return} CAuthAssignment 授权任务的信息。
public function assign($itemName,$userId,$bizRule=null,$data=null)
{
    if(!isset(
$this->_items[$itemName]))
        throw new 
CException(Yii::t('yii','Unknown authorization item "{name}".',array('{name}'=>$itemName)));
    else if(isset(
$this->_assignments[$userId][$itemName]))
        throw new 
CException(Yii::t('yii','Authorization item "{item}" has already been assigned to user "{user}".',
            array(
'{item}'=>$itemName,'{user}'=>$userId)));
    else
        return 
$this->_assignments[$userId][$itemName]=new CAuthAssignment($this,$itemName,$userId,$bizRule,$data);
}

为用户分配一个授权项目。

checkAccess() 方法
public boolean checkAccess(string $itemName, mixed $userId, array $params=array ( ))
$itemName string 需要权限检查的授权项名称
$userId mixed 用户ID。它应该是一个整数或一个字符串,代表用户的唯一标识 详情请参考IWebUser::getId
$params array 分配给用户的任务或角色的 (键-值对)形式的业务规则。
{return} boolean 用户是否有权执行操作。
public function checkAccess($itemName,$userId,$params=array())
{
    if(!isset(
$this->_items[$itemName]))
        return 
false;
    
$item=$this->_items[$itemName];
    
Yii::trace('Checking permission "'.$item->getName().'"','system.web.auth.CPhpAuthManager');
    if(
$this->executeBizRule($item->getBizRule(),$params,$item->getData()))
    {
        if(
in_array($itemName,$this->defaultRoles))
            return 
true;
        if(isset(
$this->_assignments[$userId][$itemName]))
        {
            
$assignment=$this->_assignments[$userId][$itemName];
            if(
$this->executeBizRule($assignment->getBizRule(),$params,$assignment->getData()))
                return 
true;
        }
        foreach(
$this->_children as $parentName=>$children)
        {
            if(isset(
$children[$itemName]) && $this->checkAccess($parentName,$userId,$params))
                return 
true;
        }
    }
    return 
false;
}

检查指定用户的执行权限。

clearAll() 方法
public void clearAll()
public function clearAll()
{
    
$this->clearAuthAssignments();
    
$this->_children=array();
    
$this->_items=array();
}

移除所有授权数据。

clearAuthAssignments() 方法
public void clearAuthAssignments()
public function clearAuthAssignments()
{
    
$this->_assignments=array();
}

移除所有授权分配信息。

createAuthItem() 方法
public CAuthItem createAuthItem(string $name, integer $type, string $description='', string $bizRule=NULL, mixed $data=NULL)
$name string 项目名字。这个一个是唯一标识。
$type integer 项目类型(0:操作,1:任务,2:角色)。
$description string 项目描述
$bizRule string 关联到项目的业务规则。这里是PHP代码段,当调用checkAccess时 会执行。
$data mixed 项目关联的额外数据。
{return} CAuthItem 授权项目
public function createAuthItem($name,$type,$description='',$bizRule=null,$data=null)
{
    if(isset(
$this->_items[$name]))
        throw new 
CException(Yii::t('yii','Unable to add an item whose name is the same as an existing item.'));
    return 
$this->_items[$name]=new CAuthItem($this,$name,$type,$description,$bizRule,$data);
}

创建一个授权项目。 代表动作权限的授权项目(如,创建一个内容)。 它有三种类型:操作,任务,角色。 层级授权项目。高层项目继承 低层项目的权限。

detectLoop() 方法
protected boolean detectLoop(string $itemName, string $childName)
$itemName string 父项目名字
$childName string 要添加到层级的子项目名字。
{return} boolean 返回这个循环是否存在。
protected function detectLoop($itemName,$childName)
{
    if(
$childName===$itemName)
        return 
true;
    if(!isset(
$this->_children[$childName], $this->_items[$itemName]))
        return 
false;

    foreach(
$this->_children[$childName] as $child)
    {
        if(
$this->detectLoop($itemName,$child->getName()))
            return 
true;
    }
    return 
false;
}

检查授权项目层级是否存在循环。

getAuthAssignment() 方法
public CAuthAssignment getAuthAssignment(string $itemName, mixed $userId)
$itemName string 项目名字
$userId mixed 用户ID(详情请参考IWebUser::getId)。
{return} CAuthAssignment 项目任务信息。如果没有赋予给用户, 则返回null。
public function getAuthAssignment($itemName,$userId)
{
    return isset(
$this->_assignments[$userId][$itemName])?$this->_assignments[$userId][$itemName]:null;
}

返回项目任务信息。

getAuthAssignments() 方法
public array getAuthAssignments(mixed $userId)
$userId mixed 用户ID(详情请参考IWebUser::getId)。
{return} array 用户的项目任务信息。如果没有项目赋予给用户, 则返回null。
public function getAuthAssignments($userId)
{
    return isset(
$this->_assignments[$userId])?$this->_assignments[$userId]:array();
}

返回指定用户的项目任务。

getAuthItem() 方法
public CAuthItem getAuthItem(string $name)
$name string 项目名字
{return} CAuthItem 授权项目。如果找不到该项目,则返回null。
public function getAuthItem($name)
{
    return isset(
$this->_items[$name])?$this->_items[$name]:null;
}

返回指定名字的授权项目。

getAuthItems() 方法
public array getAuthItems(integer $type=NULL, mixed $userId=NULL)
$type integer 项目类型(0:操作,1:任务,2:角色)。默认为null, 意味着返回所有类型。
$userId mixed 用户ID。默认为null,意味着即使没有赋予给用户, 也返回所有的项目。
{return} array 指定类型的授权项目。
public function getAuthItems($type=null,$userId=null)
{
    if(
$type===null && $userId===null)
        return 
$this->_items;
    
$items=array();
    if(
$userId===null)
    {
        foreach(
$this->_items as $name=>$item)
        {
            if(
$item->getType()==$type)
                
$items[$name]=$item;
        }
    }
    else if(isset(
$this->_assignments[$userId]))
    {
        foreach(
$this->_assignments[$userId] as $assignment)
        {
            
$name=$assignment->getItemName();
            if(isset(
$this->_items[$name]) && ($type===null || $this->_items[$name]->getType()==$type))
                
$items[$name]=$this->_items[$name];
        }
    }
    return 
$items;
}

返回指定类型和用户的授权项目。

getItemChildren() 方法
public array getItemChildren(mixed $names)
$names mixed 父项目名字。可以是字符串或者数组。 如果是后者,那么它是项目名字列表。
{return} array 父项目的所有子项目
public function getItemChildren($names)
{
    if(
is_string($names))
        return isset(
$this->_children[$names]) ? $this->_children[$names] : array();

    
$children=array();
    foreach(
$names as $name)
    {
        if(isset(
$this->_children[$name]))
            
$children=array_merge($children,$this->_children[$name]);
    }
    return 
$children;
}

返回指定项目的子项目

hasItemChild() 方法
public boolean hasItemChild(string $itemName, string $childName)
$itemName string 父项目名字
$childName string 子项目名字
{return} boolean 子项目是否存在
public function hasItemChild($itemName,$childName)
{
    return isset(
$this->_children[$itemName][$childName]);
}

返回值说明父授权项目是否包含子授权项目。

init() 方法
public void init()
public function init()
{
    
parent::init();
    if(
$this->authFile===null)
        
$this->authFile=Yii::getPathOfAlias('application.data.auth').'.php';
    
$this->load();
}

初始化应用组件。 这个方法是覆盖父类的方法,从PHP文件 加载授权数据。

isAssigned() 方法
public boolean isAssigned(string $itemName, mixed $userId)
$itemName string 项目名字
$userId mixed 用户ID(详情请参考IWebUser::getId)。
{return} boolean 这个项目是否已经赋予给用户。
public function isAssigned($itemName,$userId)
{
    return isset(
$this->_assignments[$userId][$itemName]);
}

返回值说明这个项目是否已经赋予给用户。

load() 方法
public void load()
public function load()
{
    
$this->clearAll();

    
$items=$this->loadFromFile($this->authFile);

    foreach(
$items as $name=>$item)
        
$this->_items[$name]=new CAuthItem($this,$name,$item['type'],$item['description'],$item['bizRule'],$item['data']);

    foreach(
$items as $name=>$item)
    {
        if(isset(
$item['children']))
        {
            foreach(
$item['children'] as $childName)
            {
                if(isset(
$this->_items[$childName]))
                    
$this->_children[$name][$childName]=$this->_items[$childName];
            }
        }
        if(isset(
$item['assignments']))
        {
            foreach(
$item['assignments'] as $userId=>$assignment)
            {
                
$this->_assignments[$userId][$name]=new CAuthAssignment($this,$name,$userId,$assignment['bizRule'],$assignment['data']);
            }
        }
    }
}

加载授权数据。

loadFromFile() 方法
protected array loadFromFile(string $file)
$file string 文件路径。
{return} array 授权数据。
protected function loadFromFile($file)
{
    if(
is_file($file))
        return require(
$file);
    else
        return array();
}

从PHP文件加载授权数据。

参见

removeAuthItem() 方法
public boolean removeAuthItem(string $name)
$name string 要移除的项目名字
{return} boolean 存储器存在的项目是否已经移除成功。
public function removeAuthItem($name)
{
    if(isset(
$this->_items[$name]))
    {
        foreach(
$this->_children as &$children)
            unset(
$children[$name]);
        foreach(
$this->_assignments as &$assignments)
            unset(
$assignments[$name]);
        unset(
$this->_items[$name]);
        return 
true;
    }
    else
        return 
false;
}

移除指定的授权项目。

removeItemChild() 方法
public boolean removeItemChild(string $itemName, string $childName)
$itemName string 父项目名字
$childName string 子项目名字
{return} boolean 是否删除成功
public function removeItemChild($itemName,$childName)
{
    if(isset(
$this->_children[$itemName][$childName]))
    {
        unset(
$this->_children[$itemName][$childName]);
        return 
true;
    }
    else
        return 
false;
}

移除子项目。 要注意的是,子项目是没有被删除的。只是它跟父项目的关系解。

revoke() 方法
public boolean revoke(string $itemName, mixed $userId)
$itemName string 项目名字
$userId mixed 用户ID(详情请参考IWebUser::getId)。
{return} boolean 撤消是否成功
public function revoke($itemName,$userId)
{
    if(isset(
$this->_assignments[$userId][$itemName]))
    {
        unset(
$this->_assignments[$userId][$itemName]);
        return 
true;
    }
    else
        return 
false;
}

撤消用户的授权任务。

save() 方法
public void save()
public function save()
{
    
$items=array();
    foreach(
$this->_items as $name=>$item)
    {
        
$items[$name]=array(
            
'type'=>$item->getType(),
            
'description'=>$item->getDescription(),
            
'bizRule'=>$item->getBizRule(),
            
'data'=>$item->getData(),
        );
        if(isset(
$this->_children[$name]))
        {
            foreach(
$this->_children[$name] as $child)
                
$items[$name]['children'][]=$child->getName();
        }
    }

    foreach(
$this->_assignments as $userId=>$assignments)
    {
        foreach(
$assignments as $name=>$assignment)
        {
            if(isset(
$items[$name]))
            {
                
$items[$name]['assignments'][$userId]=array(
                    
'bizRule'=>$assignment->getBizRule(),
                    
'data'=>$assignment->getData(),
                );
            }
        }
    }

    
$this->saveToFile($items,$this->authFile);
}

将授权数据保存到持久化存储器。 如果授权数据有任何改变, 请确保你调用的这个方法能将改变数据保存到持久存储。

saveAuthAssignment() 方法
public void saveAuthAssignment(CAuthAssignment $assignment)
$assignment CAuthAssignment 已经修改的授权信息。
public function saveAuthAssignment($assignment)
{
}

保存修改的授权信息。

saveAuthItem() 方法
public void saveAuthItem(CAuthItem $item, string $oldName=NULL)
$item CAuthItem 要保存的项目。
$oldName string 旧的项目名字。如果为null,意味着项目名字没有改变。
public function saveAuthItem($item,$oldName=null)
{
    if(
$oldName!==null && ($newName=$item->getName())!==$oldName// name changed
    
{
        if(isset(
$this->_items[$newName]))
            throw new 
CException(Yii::t('yii','Unable to change the item name. The name "{name}" is already used by another item.',array('{name}'=>$newName)));
        if(isset(
$this->_items[$oldName]) && $this->_items[$oldName]===$item)
        {
            unset(
$this->_items[$oldName]);
            
$this->_items[$newName]=$item;
            if(isset(
$this->_children[$oldName]))
            {
                
$this->_children[$newName]=$this->_children[$oldName];
                unset(
$this->_children[$oldName]);
            }
            foreach(
$this->_children as &$children)
            {
                if(isset(
$children[$oldName]))
                {
                    
$children[$newName]=$children[$oldName];
                    unset(
$children[$oldName]);
                }
            }
            foreach(
$this->_assignments as &$assignments)
            {
                if(isset(
$assignments[$oldName]))
                {
                    
$assignments[$newName]=$assignments[$oldName];
                    unset(
$assignments[$oldName]);
                }
            }
        }
    }
}

将授权项目保存到持久化存储器。

saveToFile() 方法
protected void saveToFile(array $data, string $file)
$data array 授权数据
$file string 文件路径。
protected function saveToFile($data,$file)
{
    
file_put_contents($file,"<?php\nreturn ".var_export($data,true).";\n");
}

保存授权数据到PHP文件。

参见