Куда поместить логику контроля доступа «без авторизации», кажется, не вписывается в ACL? - PullRequest
0 голосов
/ 22 января 2011

Меня интересует логика контроля доступа "без авторизации", например. Можно добавлять только дочерние задачи в задачи верхнего уровня. Кажется, он не вписывается в ACL, где он больше подходит для логики контроля доступа аутентификации / авторизации?

Я положил все в свой ACL? Я должен как-то показывать разные сообщения об ошибках, например. «Вы не можете выполнить это действие» вместо «У вас недостаточно прав для выполнения этого действия» ... как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 24 января 2011

Наиболее распространенным способом является обработка логики в плагине контроллера.В большинстве случаев это работает хорошо, но я бы рекомендовал хранить логику в ваших моделях.

ACL - это тоже модель.

Любая модель / форма / класс может реализовать Zend_Acl_Resource_Interface простопредоставив getResourceId() метод: например

abstract class My_Form_Acl extends Zend_Form {

    public function __construct() {
       // ...
       parent::__construct();
    }

    public function getResourceId()
    {
       return get_class($this);
    }
}
0 голосов
/ 22 января 2011

Вы должны обрабатывать логику доступа вне объекта списка доступа.Для этого я создал плагин 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.

...