2

我正在使用 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);
}
4

2 回答 2

0

您的方法中有太多检查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));
于 2013-03-25T14:04:13.403 回答
0

我不是 ACL 方面的专家,但据我了解,您可以根据需要allow()全部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');

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

希望这可以帮助。

于 2013-03-23T06:29:05.870 回答