Zend-Framework как обнаружить несуществующее действие с помощью zend_acl - PullRequest
0 голосов
/ 11 ноября 2010
$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
}
  • Гость имеет доступ к Contoller index и действию view .
  • Но когда он вводит url / index / view2, он должен перенаправить его на страницу ошибки, потому что действие view2 не существует
  • Но это условие говорит о том, что он разрешен только для просмотра действий. Таким образом, он не перенаправляет его на страницу ошибки, а на доступ запрещен

Как можно решить эту проблему?

Ответы [ 3 ]

3 голосов
/ 11 ноября 2010

Вы можете проверить наличие ресурса (действия) в acl:

if(!$this->_acl->has($resource) || $this->_acl->isAllowed($role, $resource, $action))

Иначе можно просто отрицать по умолчанию. Если затем вы проверите несуществующее действие, acl вернет false по умолчанию.
Если вы просто хотите определить, вызывается ли несуществующее действие с вашего контроллера, вы можете использовать метод контроллера __call.

Для более конкретного решения вы должны предоставить больше информации, например, о том, где вы выполняете ACL-проверку, как вы настраиваете 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 не вызывала никаких исключений, поскольку ресурс (или действие) не найден. В зависимости от того, где вы проводите проверку, у вас есть несколько возможностей сделать это, но при условии, что каждый контроллер - это один ресурс, и вы все добавляете их, это не должно быть проблемой.

1 голос
/ 13 ноября 2010

Я вызываю ACL в предзапуске плагина frontcontroller

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 );
    }           
}
0 голосов
/ 11 ноября 2010

Я бы сделал это, выдав исключение 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)
}

Стандартные исключения будут обрабатываться какобычно.

...