繁体   English   中英

PHP应用程序中的访问控制体系结构

[英]Access control architecture in a PHP application

我试图弄清楚如何限制当前正在研究的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;
    }
}

然后,我将在Application Bootstrap中执行以下操作:

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

在我的控制器中(因为我听说这是您应该放置访问控制的位置),我将遇到以下情况:

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您将执行基本控制,例如:

$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

zend框架中的动态自定义ACL?

要更高级地使用断言,请查看:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM