$this->add ( new Zend_Acl_Resource ( 'index' ) );
$this->addRole ( new Zend_Acl_Role ( 'guest' ) );
$this->allow('guest', 'index','view');
我在这种情况下遇到问题
if (! $this->_acl->isAllowed ( $role, $resource, $action )){
... redirect to access denied
}
如何解决这个问题?
答案 0 :(得分:3)
您可以检查acl中存在的资源(操作):
if(!$this->_acl->has($resource) || $this->_acl->isAllowed($role, $resource, $action))
其他人可以默认拒绝。如果您然后检查不存在的操作,则默认情况下acl将返回false 如果您只想检测是否从控制器调用了不存在的操作,则可以使用控制器的__call方法。
对于更具体的解决方案,您应该提供更多信息,例如您执行acl-check的位置,如何设置您的acl,....
捕获控制器中不存在的操作的示例:
My_Controller extends Zend_Controller_Action
{
__call($method, $args)
{
throw new Exception("Action does not exist"); // This is done by default
// Just do whatever you want to do in this function (like redirecting)
}
}
无论如何,即使没有魔术功能,也可以使用ErrorhandlerPlugin完成。由于您只想重定向到错误页面,实际上只需要注意,acl检查不会抛出任何异常,因为找不到资源(或Action)。根据您的检查位置,您有几个可行性,但假设每个控制器都是一个资源,并且您所有添加它们,这应该不是问题。
答案 1 :(得分:1)
我在frontcontroller的frontcontroller插件中调用ACL
public function preDispatch(Zend_Controller_Request_Abstract $request) {
if ($this->_auth->hasIdentity ()) {
$rights = $this->_auth->getIdentity ()->rights;
if ($rights == 2) {
$role = 'admin';
} elseif ($rights == 1) {
$role = 'user';
} else {
$role = 'guest';
}
} else {
$role = 'guest';
}
$controller = $request->controller;
$action = $request->action;
$module = $request->module;
$resource = $controller;
if ($this->_acl->has ( $resource )) {
if (! $this->_acl->isAllowed ( $role, $resource, $action )) {
if (! $this->_auth->hasIdentity ()) {
//redirect to login
$module = $this->_noauth ['module'];
$controller = $this->_noauth ['controller'];
$action = $this->_noauth ['action'];
} else {
//redirect to access denied
$module = $this->_noacl ['module'];
$controller = $this->_noacl ['controller'];
$action = $this->_noacl ['action'];
}
$request->setModuleName ( $module );
$request->setControllerName ( $controller );
$request->setActionName ( $action );
}
} else {
//controller not found
$module = ('default');
$controller = ('error');
$action = ('not-found');
$request->setModuleName ( $module );
$request->setControllerName ( $controller );
$request->setActionName ( $action );
}
}
答案 2 :(得分:0)
我会通过抛出NotAllowed
例外来做到这一点。
if (! $this->_acl->isAllowed ( $role, $resource, $action )){
throw new YourNotAllowedException('some error message');
}
然后在错误控制器中我会处理这个异常:
if ($error->exception instanceof NotAllowed) {
// manual forward setting request params
// (url remains the same, but user sees the login page)
}
标准例外将照常处理。