我正在开展一个网络项目,其中一些访问决策取决于页面本身(例如/logout
,只有登录用户才能看到)并且有些依赖于动态模型对象(例如/article/delete/1234
我们必须检查登录用户是否写了1234
,或者他是否是管理员。)
现在,我正面临着如何将两者结合在一起的问题。无论我如何尝试,我都不能单独依赖这两个中的任何一个:
Comment
只是comment
而不是default/comment
{1}}。 Comment
不限于默认模块,也可以在管理模块中使用。使用模块化ACL 我试图检查每个页面是否允许用户访问它,例如
if (!$acl->isAllowed($user, 'default/secrets', 'mysecrets')) {
$this->forward('auth', 'login');
$this->setDispatched(false);
}
使用动态断言我正在检查是否允许某人编辑特定的模型对象。
// $comment has a method getResourceId() returning 'comment'
if ($acl->isAllowed($user, $comment, 'delete')) {
// display a link for deletion
}
当然,检查
会很好会是一样的,但我想这是不可能的,我必须创建两个规则:
$acl->allow('member', 'default/comment', 'delete');
$acl->allow('member', 'comment', 'delete', new Acl_Assert_CommentAuthor());
$acl->allow('admin', 'comment', 'delete');
现在,这对我来说似乎并不完美,因为在某些情况下这会导致重复工作。
有没有更好的方法来解决这个问题?或者是至少创建一致的命名方案的唯一方法,例如:mvc:default/comment
,model:comment
答案 0 :(得分:0)
我这样做的方式,自定义sql查询限制结果,在插入/删除/修改sql之前检查的函数
然后我编写的ACL插件检查权限并使用这5个表
acl_groups
acl_permession
acl_permession_groups
acl_permession_risource
acl_risource
代码:
class Abc_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
/**
* Return whether a given request (module-controller-action) exists
*
* @param Zend_Controller_Request_Abstract $request Request to check
* @return boolean Whether the action exists
*/
private function _actionExists(Zend_Controller_Request_Abstract $request)
{
$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
// Check controller
if (!$dispatcher->isDispatchable($request)) {
return false;
}
$class = $dispatcher->loadClass($dispatcher->getControllerClass($request));
$method = $dispatcher->formatActionName($request->getActionName());
return is_callable(array($class, $method));
}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
// fetch the current user
$controller = $request->controller;
$action = $request->action;
$logger = Zend_Registry::get('log');
//prima controlla se sei autenticato e poi controlla se l'azione esiste, cosi non esponi il sito
$auth = Zend_Auth::getInstance(); /* @var $auth Zend_Auth */
if($auth->hasIdentity()) {
if(! $this->_actionExists($request))//l'azione non esiste?
{
$request->setControllerName('error');
$request->setActionName('pagenotfound');
$logger->notice( " IP: ". $_SERVER['REMOTE_ADDR']. " http://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]. " ?" .http_build_query($_REQUEST));
return ;
}
$allowed = Abc_Action_Helper_CheckPermission::checkPermission($controller, $action);
if ($allowed !== 1)
{
$request->setControllerName('error');
$request->setActionName('noauth');
}
//fine azione esiste
}else{
$request->setControllerName('user');
$request->setActionName('login');
return ;
}
}//fine preDispatch
}
然后您可以添加您的代码(我为了简短而省略)以记住请求并在登录后将其重定向到那里。