我正在试图弄清楚如何限制我目前正在处理的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());
}
在我的控制器中(因为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。
答案 0 :(得分: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