Zend Acl-当acl规则返回false时,断言是否可能允许访问特权? [英] Zend Acl - is it possible for an assertion to allow access to a privilege when the acl rules return false?

查看:114
本文介绍了Zend Acl-当acl规则返回false时,断言是否可能允许访问特权?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

默认情况下,即使acl规则允许,在断言中返回false也会拒绝访问。我想做的是反过来-即在acl规则拒绝它时在断言中返回true以允许访问。

By default, returning false in an assertion denies access even when the acl rules allow it. What I want to do is the other way round - i.e. return true in an assertion to allow access when the acl rules deny it.

例如:

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不允许我询问的特权

The above isAllowed() will return false because the privilege I am asking about is not allowed in the acl rules, therefore it isn't getting as far as the assertion.

我想要的可能吗?

我要执行此操作的原因是,用户可能对所有页面都具有某些特权,然后对他们创建的页面拥有不同的特权集-在查询特权时,我希望能够知道页面是否属于他们以及是否也就是说,将规则应用于本页面而不是页面。显然,在实际应用中,传递的是用户和页面对象,而不是字符串。

The reason I want to do this is that a user may have certain privileges for all pages and then a different set of privileges for pages they have created - when querying for a privilege I want to be able to tell if the page is theirs and if it is, apply the rules for "own-page" rather than "page". Obviously in the real app, user and page objects are passed instead of strings.

更新:我已经成功地通过子类化来完成我想做的事情Zend_Acl。

UPDATE: I have managed to do what I want by subclassing Zend_Acl.

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

This class allows callbacks to be added for specific role and resource combinations. When isAllowed() is invoked, the callback, if it exists, is run. It is passed in the same parameters as an assertion (as well as the result of parent::isAllowed()). The return value of this callback is return from isAllowed(), unless it is null, in which case the normal return value is used.

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.


推荐答案

听起来像您想要的东西类似:

Sounds like you want something along the lines of:

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');

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

Here you would expect the user to be able to read any page but only write to their own pages.

这篇关于Zend Acl-当acl规则返回false时,断言是否可能允许访问特权?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆