Php Zend Acl-当Acl规则返回false时,断言是否允许访问权限?

Php Zend Acl-当Acl规则返回false时,断言是否允许访问权限?,php,zend-framework,acl,Php,Zend Framework,Acl,默认情况下,即使acl规则允许,在断言中返回false也会拒绝访问。我想做的是另一种方法,即在断言中返回true,以便在acl规则拒绝访问时允许访问 例如: class TestAssert implements Zend_Acl_Assert_Interface { public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $role = null, Zend_Acl_Resource_Interface $resour

默认情况下,即使acl规则允许,在断言中返回false也会拒绝访问。我想做的是另一种方法,即在断言中返回true,以便在acl规则拒绝访问时允许访问

例如:

class TestAssert implements Zend_Acl_Assert_Interface
{
    public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $role = null, Zend_Acl_Resource_Interface $resource = null,
                           $privilege = null)
    {
        return true;
    }
}

$acl = new Zend_Acl;
$acl->addResource('page');
$acl->addRole('user');

$acl->allow('user', 'page', 'read', new TestAssert);
$acl->isAllowed('user', 'page', 'write');
上面的isAllowed()将返回false,因为acl规则中不允许我询问的特权,因此它没有达到断言的程度

我想要的可能吗

我想这样做的原因是,用户可能对所有页面都有特定的权限,然后对他们创建的页面有一组不同的权限-在查询权限时,我希望能够判断页面是否是他们的,如果是,则应用“自己的页面”而不是“页面”的规则。显然,在真正的应用程序中,传递的是用户和页面对象,而不是字符串

更新:我已经通过子类化Zend_Acl实现了我想要的功能

此类允许为特定角色和资源组合添加回调。调用isAllowed()时,将运行回调(如果存在)。它以与断言相同的参数传递(以及parent::isAllowed()的结果)。此回调的返回值是从isAllowed()返回的,除非它为null,在这种情况下使用正常的返回值

class Acl extends Zend_Acl
{
    protected $_callbacks = array();

    /**
     * Takes into account the callback to determine whether the role is allowed access
     * 
     * @param Zend_Acl_Role_Interface $role
     * @param Zend_Acl_Resource_Interface $resource
     * @param string $privilege
     * @return bool
     */
    public function isAllowed($role = null, $resource = null, $privilege = null)
    {
        $result = parent::isAllowed($role, $resource, $privilege);
        $role = $this->getRole($role)->getRoleId();
        $resource = $this->get($resource)->getResourceId();

        if(isset($this->_callbacks[$role][$resource]))
        {           
            $callbackResult = call_user_func($this->_callbacks[$role][$resource], $this, $role, $resource, $privilege, $result);
        }

        return isset($callbackResult) ? $callbackResult : $result;
    }

    /**
     * Add a callback for a specific role and resource combination.
     * If the callback returns a value, this is used as the return value for isAllowed().
     * Otherwise, if the callback returns null, the normal result of isAllowed() will be used.
     * 
     * @param Zend_Acl_Role_Interface $role
     * @param Zend_Acl_Resource_Interface $resource
     * @param callback $callback 
     */
    public function addCallback($role, $resource, $callback)
    {
        $role = $this->getRole($role)->getRoleId();
        $resource = $this->get($resource)->getResourceId();
        $this->_callbacks[$role][$resource] = $callback;
    }
}
用法:

$acl = new Acl;
$acl->addResource('page');
$acl->addRole('user');

$acl->addCallback('user', 'page', function($acl, $role, $resource, $privilege, $result)
{
    return true;
});


$acl->allow('user', 'page', array('read'));
$acl->isAllowed('user', 'page', 'edit'); //returns true even though 'edit' is not allowed.

听起来你想要的东西大致如下:

class WriteAssert implements Zend_Acl_Assert_Interface
{
    public function assert(Zend_Acl $acl,
                           Zend_Acl_Role_Interface $role = null,
                           Zend_Acl_Resource_Interface $resource = null,
                           $privilege = null)
    {
        // return whether the user owns the page
    }
}

$acl = new Zend_Acl;
$acl->addResource('page');
$acl->addRole('user');

$acl->allow('user', 'page', 'read');
$acl->allow('user', 'page', 'write', new WriteAssert);
$acl->isAllowed('user', 'page', 'write');

在这里,您希望用户能够阅读任何页面,但只能对自己的页面进行写入。

听起来您需要以下内容:

class WriteAssert implements Zend_Acl_Assert_Interface
{
    public function assert(Zend_Acl $acl,
                           Zend_Acl_Role_Interface $role = null,
                           Zend_Acl_Resource_Interface $resource = null,
                           $privilege = null)
    {
        // return whether the user owns the page
    }
}

$acl = new Zend_Acl;
$acl->addResource('page');
$acl->addRole('user');

$acl->allow('user', 'page', 'read');
$acl->allow('user', 'page', 'write', new WriteAssert);
$acl->isAllowed('user', 'page', 'write');

在这里,您希望用户能够读取任何页面,但只能写入自己的页面。

问题是,我希望自己的页面规则是不同的资源(因为它们将存储在数据库中,并从管理面板编辑)。因此,当在页面上调用isAllowed()以查看是否允许写入访问时,如果用户拥有该页面,我希望测试“own page”资源,而不仅仅是“page”。据我所知,断言无法做到这一点问题是,我希望自己的页面规则是不同的资源(因为它们将存储在数据库中,并从管理面板编辑)。因此,当在页面上调用isAllowed()以查看是否允许写入访问时,如果用户拥有该页面,我希望测试“own page”资源,而不仅仅是“page”。就我所知,断言无法做到这一点