Вы должны обрабатывать логику доступа вне объекта списка доступа.Для этого я создал плагин frontController:
class Soflomo_Controller_Plugin_Access extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup (Zend_Controller_Request_Abstract $request)
{
if (!$this->_isAllowed($request)) {
throw new Zend_Controller_Action_Exception('No permission', 403);
}
}
protected function _isAllowed (Zend_Controller_Request_Abstract $request, $permission = 'view')
{
$acl = new Acl(); // Here your logic to fetch a (cached) ACL
$role = new User(); // Here your logic to fetch role
$resource = new Page(); // Here your logic to fetch resource
return $acl->hasRole($role)
&& $acl->has($resource)
&& $acl->isAllowed($role, $resource, $permission);
}
}
В этом случае я явно проверяю наличие роли и ресурса.Это потому, что у меня есть только правила ACL в моей базе данных, где роль имеет доступ к ресурсу.Во всех других случаях (когда у пользователя нет доступа) я оставляю его вне базы данных.
Когда у вас другая логика, возможно, достаточно проверить на $acl->isAllowed($role, $resource, $permission);
и оставить $acl->hasRole()
и$acl->has()
out.
Обработчик ошибок
Я выкидываю исключение Zend_Controller_Action_Exception с кодом ошибки 403, но если вы не перехватите конкретный код, он будет выглядеть какнормальная ошибка приложения.Поэтому я добавил в плагин frontController ErrorHandler еще одну константу EXCEPTION_NO_PERMISSION
и добавил ее в оператор switch:
case 'Zend_Controller_Action_Exception':
if (404 == $exception->getCode()) {
$error->type = self::EXCEPTION_NO_ACTION;
} elseif (403 == $exception->getCode()) {
$error->type = self::EXCEPTION_NO_PERMISSION;
} else {
$error->type = self::EXCEPTION_OTHER;
}
break;
Затем вы можете получить тип ошибки EXCEPTION_NO_PERMISSION
в вашем ErrorController.