【问题标题】:Zend ACL with Modules and Controller access issuesZend ACL 与模块和控制器访问问题
【发布时间】:2012-05-02 00:26:05
【问题描述】:

我已经为此工作了几天无济于事。

使用 ZF Boilerplate,我正在尝试设置一个包含模块的 ACL(因为我的架构中有一些具有相同名称的控制器,并且无法更改)。 我以为我已经很好地工作了,只是意识到永远不会处理访问,我想我缺少一些东西,但我不确定是什么。

这是我的设置:

library/App/Action/Helpers/PrivilegesManage.php 中的助手

<?php 
class App_Action_Helpers_PrivilegesManage extends Zend_Controller_Action_Helper_Abstract
{
//the acl object
public $acl;
//the constructor of the our ACL
public function __construct()
{
    $this->acl = new Zend_Acl();
}

//function that sets roles for the people
public function setRoles()
{
    $this->acl->addRole(new Zend_Acl_Role('guest'));
    $this->acl->addRole(new Zend_Acl_Role('crew'));
    $this->acl->addRole(new Zend_Acl_Role('client'));
    $this->acl->addRole(new Zend_Acl_Role('admin'));
}

//function that set the resources to be accessed on the site
public function setResources()
{
    $this->acl->add(new Zend_Acl_Resource('site:error'));
    $this->acl->add(new Zend_Acl_Resource('site:index'));
    //me
    $this->acl->add(new Zend_Acl_Resource('me:clients'));
    $this->acl->add(new Zend_Acl_Resource('me:crew'));
    $this->acl->add(new Zend_Acl_Resource('me:error'));
    $this->acl->add(new Zend_Acl_Resource('me:index'));
    $this->acl->add(new Zend_Acl_Resource('me:jobs'));
    $this->acl->add(new Zend_Acl_Resource('me:people'));
    $this->acl->add(new Zend_Acl_Resource('me:system'));
    //admin
    $this->acl->add(new Zend_Acl_Resource('admin:clients'));
    $this->acl->add(new Zend_Acl_Resource('admin:crew'));
    $this->acl->add(new Zend_Acl_Resource('admin:error'));
    $this->acl->add(new Zend_Acl_Resource('admin:index'));
    $this->acl->add(new Zend_Acl_Resource('admin:jobs'));
    $this->acl->add(new Zend_Acl_Resource('admin:people'));
    $this->acl->add(new Zend_Acl_Resource('admin:system'));
}

//function that sets the privileges for the different roles
public function setPrivileges()
{
    $this->acl->allow('guest', 'site:error', 'index');
    $this->acl->deny('guest', 'site:index', 'index');

    $this->acl->allow('crew', 'site:index');
    $this->acl->allow('crew', 'site:error');
    $this->acl->allow('crew', 'me:crew');       
    $this->acl->allow('client', 'me:clients');
    $this->acl->allow('client', 'site:index', array('logout'));
    $this->acl->deny('client', 'me:crew');
    $this->acl->deny('guest', 'admin:crew', array('add'));

}

public function setAcl()
{
    Zend_Registry::set('acl', $this->acl);
}
?>

然后我在 App/Plugin/Acl.php 中也有一个插件 [EDITED]

<?php
class App_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
/**
 *
 * @var Zend_Auth
 */
protected $_auth; //Zend_Auth instance for user access

protected $_acl; //Zend_Acl instance for user privileges
protected $_module;
protected $_action;
protected $_controller;
protected $_currentRole;
protected $_resource;

public function __construct(Zend_Acl $acl, array $options = array()) {
    $this->_auth = Zend_Auth::getInstance();
    $this->_acl = $acl;

}

 public function preDispatch(Zend_Controller_Request_Abstract $request) {

    $this->_init($request);

   if ($this->_acl->has($this->_resource)) {
        // if the current user role is not allowed to do something
        if (!$this->_acl->isAllowed($this->_currentRole, $this->_resource, $this->_action)) {

            if ('guest' == $this->_currentRole) {
                $request->setModuleName('site');
                $request->setControllerName('index');
                $request->setActionName('login');
            } 
            else {
                $request->setModuleName('site');
                $request->setControllerName('error');
                $request->setActionName('denied');

            }
        }
    }
}

protected function _init($request) 
{
    $this->_module = $request->getModuleName();
    $this->_action = $request->getActionName();
    $this->_controller = $request->getControllerName();
    $this->_currentRole = $this->_getCurrentUserRole();
    $this->_resource = $this->_module  . ':' . $this->_controller; 
}

protected function _getCurrentUserRole() 
{      

    if($this->_auth->hasIdentity()) {
        $authData = $this->_auth->getIdentity();
        //$role = isset($authData->myType())?strtolower($authData->property->privilage): 'guest';
        //retrieving the UserType
            $authTypeCheck = $authData->myType();
        if(isset($authTypeCheck)){
            $role = strtolower($authData->myType());
        }
    } else {
        $role = 'guest';
    }
    return $role;
}
}
?>

现在在这里,似乎 $acl 从来没有任何资源,当我打印出 $acl 的内容时,我确实得到了一些资源。

最后在引导程序中我有:

    protected function _initAclControllerPlugin() {

    $this->bootstrap('frontcontroller');


    $front = Zend_Controller_Front::getInstance();
    $aclhelper= new App_Action_Helpers_PrivilegesManage();
    $aclhelper->setRoles();
    $aclhelper->setResources();
    $aclhelper->setPrivileges();
    $aclhelper->setAcl();

    $aclPlugin = new App_Plugin_Acl($aclhelper->acl);
    $front->registerPlugin($aclPlugin);
}

我是 Zend 的新手,尤其是 ACL,因此非常欢迎任何建议和帮助。

【问题讨论】:

    标签: php zend-framework module acl


    【解决方案1】:

    您没有定义您的资源,请在您的 acl 插件中执行此操作

    protected function _init($request) 
    {
    
        $this->_module = $request->getModuleName();
        $this->_action = $request->getActionName();
        $this->_controller = $request->getControllerName();
        $this->_currentRole = $this->_getCurrentUserRole();
       $this->_resource = $this->_module  . ':' . $this->_controller; // <-----
    }
    

    【讨论】:

    • u_u 傻我我一定是愚蠢地删除了这行,我会试一试!非常感谢!编辑:它有效,但现在 setPrivileges 中设置的规则根本不起作用......
    【解决方案2】:

    可能和这个方法有关:

    protected function _getCurrentUserRole() 
    {      
    
        if($this->_auth->hasIdentity()) {
            $authData = $this->_auth->getIdentity();
            //$role = isset($authData->myType())?strtolower($authData->property->privilage): 'guest';
            //retrieving the UserType
                $authTypeCheck = $authData->myType();
            if(isset($authTypeCheck)){
                $role = strtolower($authData->myType());
            }
        } else {
            $role = 'guest';
        }
        return $role;
    }
    

    看起来如果 $authTypeCheck 未设置,则角色未定义。不确定 $authData->myType() 究竟做了什么,但这可能是原因。

    您可以尝试在 if(isset($authTypeCheck)){ // } else { $role = 'guest'; }

    在注释行之一中仔细查看了与此类似的代码。

    抱歉,如果不是这样,至少与我的用例相比,您采用了一种看起来相当复杂的方法。您可能可以将所有代码包装到 Acl Plugin Predispatch 方法中,这可能会排除很多可能的问题。

    【讨论】:

      猜你喜欢
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多