【问题标题】:How to allow non-existent privileges in Zend_Acl?如何在 Zend_Acl 中允许不存在的权限?
【发布时间】:2013-03-12 11:58:58
【问题描述】:

我正在使用 ZF 1.12.2,我想为我的 Zend_Acl 权限创建一个黑名单,因为我的限制比允许少。我的 ACL 资源名称基于我的控制器名称,我的权限基于我的控制器操作名称。

现在,我拒绝这样的特权:

$acl->deny('user', null, 'User::login');

当我向我的用户控制器添加操作时,我希望用户角色被隐式授予对它们的访问权限,除非我明确拒绝它们。所以,如果我在我的用户控制器上添加一个编辑操作,我不必这样做:

$acl->allow('user', null, 'User::edit');

默认情况下,Zend_Acl::isAllowed 如果权限不存在则返回 false。除非我在调用父级之前对它们进行子类化并存储它们,否则也很难知道添加了哪些特权。我一直在尝试破译Zend_Acl::$_rules,因为我认为它会满足我的需要并且我可以避免子类化。允许不存在的权限通过Zend_Acl::isAllowed 可能吗?

更新:现在,我的工作子类方法My_Acl::isAllowed 如下。 My_Acl::__construct 接受一个数组配置,其中包含要添加的嵌套权限/资源的角色。

public function isAllowed($role = null, $resource = null, $privilege = null)
{
    if (null !== $resource) {
        if (is_string($resource)) {
            $resource_id = $resource;
        } else {
            $resource_id = $resource->getResourceId();
        }

        if (!in_array($resource_id, array_keys($this->_resources))) {
            return true;
        }
    }

    if (null !== $privilege) {
        if (!in_array($privilege, array_keys($this->_privileges))) {
            return true;
        }
    }

    return parent::isAllowed($role, $resource, $privilege);
}

【问题讨论】:

  • 您可以在检查访问权限的插件中添加代码吗? 'controller::action' 这部分基本上是。
  • @roko 添加了我的覆盖 isAllowed 方法

标签: php zend-framework acl privileges blacklist


【解决方案1】:

我不是 ACL 专家,但据我了解,您可以先allow() all,然后根据需要deny()

//user can do all, by not specifying resources or privileges, all is allowed
$acl->allow('user');

//explicitly deny specific resources and privileges
$acl->deny('user', null, 'User::login');

请注意应用的任何继承,因为这可能会导致意外行为。

希望这会有所帮助。

【讨论】:

  • 抱歉,这不起作用。检查 $acl->isAllowed('user', null, 'bogusPrivilege') 返回 false。
【解决方案2】:

您的 isAllowed 方法中有太多检查,这使事情变得复杂

如果您不使用模块化方法 (HMVC),则应使用 isAllowed(role, resource, privilege) 的第二个参数,可以将控制器用作第二个参数,将操作用作第三个参数,如下所示:$acl->allow('user', 'user', 'edit');

如果您采用这种方法,则需要将控制器添加为资源

//user controller as resource.
$this->add(new Zend_Acl_Resource('user'));   

定义任意资源:nullresources

// any resource
$this->add(new Zend_Acl_Resource('nullresources'));       

$this->addRole(new Zend_Acl_Role('guest')); // guest role - no login (it's good to have something like this)

$this->allow('guest', 'nullresources');

如果您添加任意资源:nullresources,您可以跳过 isAllowed 中的一些步骤。

  /**
   *
   * @param string $role
   * @param string $resource (module name)
   * @param String $privilege (controller name: action name)
   * @return Boolean
   */
  public function isAllowed($role = null, $resource = null, $privilege = null)
  {
      /**
       *  by default, undefined resources are allowed to all
       */
      if (!$this->has($resource)) {
          $resource = 'nullresources';
      }
      return parent::isAllowed($role, $resource, $privilege);
  }

如果你遵循这种方法,你应该能够以这种方式使用它:

$acl->allow('user', 'user');
$acl->deny('user', 'user', 'login');

编辑:

您还需要更改您进行检查的位置,即引导程序或某些插件,如果您使用插件,这里是一个示例类

<?php 
class My_Acl_AccessCheck extends Zend_Controller_Plugin_Abstract
{
    private $_acl = null;

    public function __construct(Zend_Acl $acl)
    {
        $this->_acl = $acl;
    }

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {            
        /**
         * get controller name
         * @var String $controller
         */
        $controller = $request->getControllerName();
        /**
         * get action name
         * @var String $action
         */
        $action = $request->getActionName();
        /**
         * getting the role from the registry and defining some
         * role for the null character as guest makes authentication more flexible
         * if the roles is not allowed to use the resource then the user is
         * redirected to action notAllowed of controller user
         *
         * Parameter passed for isAllowed: role, ControllerName, ActionName             
         */
        if(!$this->_acl->isAllowed(Zend_Registry::get('role'), $controller, $action))
        {
            $request->setModuleName('default')
                    ->setControllerName('user')
                    ->setActionName('notAllowed');
        }        

    }
}

bootstrap

    $this->_acl = new My_Acl();
    $frontController = Zend_Controller_Front::getInstance();
    $frontController->registerPlugin(new My_Acl_AccessCheck($this->_acl));

【讨论】:

  • 我确实喜欢您在覆盖子类方法中最初允许的空资源和资源检查。然而,使用 Zend_Acl 检查特权的存在是另一回事。是否可以调整 Zend_Acl 以允许对特权使用黑名单方法并以这种方式拒绝对角色的访问,同时允许其他一切?我真的很想避免重复自己是 Zend_Acl 中存在的代码。
  • 我对你的方法有点困惑。您如何将您的角色映射到特权以及$this-&gt;_privileges 持有什么?对角色的黑名单(拒绝)操作?如果您将角色映射到权限是正确的,那么您的方法也应该有效。你的方法会做与 Zend_Acl 类似的事情,我仍然不确定你为什么不允许 Zend_Acl 检查这些东西。这又是如何让自己重复的呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2019-04-22
相关资源
最近更新 更多