【问题标题】:Access control architecture in a PHP applicationPHP 应用程序中的访问控制架构
【发布时间】:2012-02-10 09:27:28
【问题描述】:

我正在尝试弄清楚如何限制对我目前正在处理的 PHP 项目中特定资源的访问。我一直在寻找现有的解决方案,但没有一个真正符合我的需要(例如 Zend_Acl)。

现在我想出了这样的事情:(当然,这是非常、非常简化的。没有例外或其他任何情况。足以理解重点)

class Access {
    protected $_context;
    protected $_handlers;
    public function __construct($context) {
        $this->_context = $context;
    }
    public static function registerHandler(Access_Handler $handler) {
        $key = $handler->getContextType().'/'.$handler->getResourceType();
        self::$_handlers[$key] = $handler;
    }
    public function isAllowed($resource) {
        return $this->getHandler($resource)->isAllowed($this->_context, $resource);
    }
    public function getHandler($resource) {
        // Look for and return the appropriate handler for the combination of 
        // $context and $resource
    }
}

abstract class Access_Handler {
    $_contextType;
    $_resourceType;
    abstract public function isAllowed();
}

class Access_Handler_UserInvoice extends Access_Handler {
    $_contextType = 'User';
    $_resourceType = 'Invoice';
    public function isAllowed($user, $invoice) {
        if($invoice->user_id === $user->id) {
            return true;
        }
        return false;
    }
}

然后我会在我的应用程序引导中执行类似的操作:

protected function $_initAccessHandlers() {
    Access::registerHandler(new Access_Handler_UserInvoice());
}

在我的控制器中(因为 I've heard 那是你应该放置访问控制的地方)我会有这样的东西:

class InvoiceController {
    public function viewAction() {
        // $this->me is of type User
        $access = new Access($this->me);
        if($access->isAllowed($this->invoice)) {
            // ...
        }
    }
}

我没有测试过代码,所以可能有错别字或其他错误,但我想你明白了要点。此外,实际上我可能会将 Access 实现为 Singleton 或 Multiton,但这不是我的问题所在。

这是正确的做法吗?这对我来说似乎很自然,但我想知道为什么没有其他人以这种方式这样做。

我的开发栈是 PHP/MySQL/Zend Framework/Doctrine。

【问题讨论】:

  • 您在这里尝试做的所有事情都已经在 Zend_Acl 中使用动态断言完成了,不是吗?
  • 在我的情况下有点复杂。例如,我希望用户能够访问其同事(属于同一公司)的发票,但不能修改它们。 AFAIK,这对于 Zend_Acl 来说是非常困难的,如果不是不可能的话。 (我还没有研究 Zend_Acl_Assert_Interface ..这是我想要的吗?)

标签: php model-view-controller acl


【解决方案1】:

使用Zend_Acl,您将执行基本控制,例如:

$acl = new Zend_Acl();
$acl->add(new Zend_Acl_Resource('article'));
$acl->addRole(new Zend_Acl_Role('author'));
$acl->deny();
$acl->allow('author', 'article', array('list'));

然后你可以使用断言来做你想做的事:

$user = Zend_Auth::getInstance()->getIdentity();
$assertion = new My_Acl_Assertion_ArticleEditCheck($user);
$acl->allow('author', 'article', 'edit', $assertion);

您可以不将用户对象传递给断言,而是将其实现为内部属性,并在必要时处理请求参数。

参考资料:

http://framework.zend.com/manual/en/zend.acl.advanced.html

Dynamic custom ACL in zend framework?

有关断言的更高级使用,请查看:

http://www.aviblock.com/blog/2009/03/19/acl-in-zend-framework/

http://ralphschindler.com/2009/08/13/dynamic-assertions-for-zend_acl-in-zf

【讨论】:

    猜你喜欢
    • 2018-08-18
    • 2016-04-08
    • 2018-08-12
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    • 2011-07-12
    • 2015-01-21
    • 1970-01-01
    相关资源
    最近更新 更多