ZF2 - проверка прав доступа для параметра get в каждом действии - PullRequest
0 голосов
/ 16 октября 2018

У меня есть контроллер с именем «TestController» и несколько действий в нем.За каждое действие я получаю параметр получения («id»).Что-то вроде:

test/action1/1
test/action1/2
test/action2/1
test/action3/1
...

Поскольку этот параметр можно легко изменить, я хочу проверить разрешения для этого идентификатора.Нужно ли включать этот метод проверки в каждое отдельное действие или есть другой способ?Я знаю, что не могу получить params в конструкторе, но такой способ был бы хорош.

Мое решение на данный момент было бы иметь метод check в плагине и вызывать его в каждом действии, подобном этому:

if(!$this->access()->checkAccess(..., $this->params()->fromRoute('id')) {
 //redirect...
}

1 Ответ

0 голосов
/ 16 октября 2018

Вы можете использовать ACL (или RBAC) для выполнения этих проверок.

С помощью ACL вы можете (должны) декларировать ресурсы вашего приложения, роли, которые используют приложение, и то, как роли получают доступ к ресурсам.

Вы можете начать с присоединения слушателя к контроллерам, в Module.php

class Module {
    public function onBootstrap(\Zend\Mvc\MvcEvent $event) {
        $application = $e->getApplication();
        $serviceManager = $application->getServiceManager();
        $sharedManager = $application->getEventManager()->getSharedManager();

        $router = $serviceManager->get('router');
        $request = $serviceManager->get('request');

        $matchedRoute = $router->match($request);
        if (null !== $matchedRoute) {
            $sharedManager->attach(\Zend\Mvc\Controller\AbstractActionController::class, \Zend\Mvc\MvcEvent::EVENT_DISPATCH, function($event) use ($serviceManager) {
                $serviceManager->get('ControllerPluginManager')->get('Application\Controller\Plugin\Acl')->doAuthorization($event);
            }, 2
            );
        }
    }
}

приложения. Как вы можете видеть, мы прикрепили плагин Application\Controller\Plugin\Acl к событию dispatchкаждые Zend\Mvc\Controller\AbstractActionController.

Затем вы должны реализовать свой ACLS.

Вот простой пример.По умолчанию я предпочитаю запретить доступ ко всем ресурсам, а затем поочередно разрешать доступ к ним.Вы также можете разрешить доступ ко всему, а затем запретить доступ к отдельным ресурсам, но в этом случае вам нужно быть более осторожным.Если вы все отрицаете и что-то забываете, пользователь не сможет получить доступ к тому, чем он должен быть.Если вы разрешите все и забудете что-то, пользователь может увидеть то, чего не должен делать.Лучше быть в безопасности, чем потом сожалеть;)

namespace Application\Controller\Plugin;

class Acl extends \Zend\Mvc\Controller\Plugin\AbstractPlugin implements \Zend\ServiceManager\ServiceLocatorAwareInterface {

    private $serviceLocator;

    public function doAuthorization(\Zend\Mvc\MvcEvent $event) {
        // Retrieve user role, if you have them or just use guest
        $role = 'guest';

        $resource = get_class($event->getTarget());
        $action = $event->getRouteMatch()->getParams()['action'];

        if (!$this->getAcl()->isAllowed($role, $resource, $action)) {
            // Handle the access denied
            // Could be a redirect to login/home page, or just an 404 page
        }

    }

    public function getAcl() {
        // Create the ACL object
        $acl = new \Zend\Permissions\Acl\Acl();

        // Add your roles
        $acl->addRole(new \Zend\Permissions\Acl\Role\GenericRole('guest'));

        // Add your resources
        $acl->addResource(new Resource(\YourModule\Controller\YourController::class));

        // By default, block access to all resources.
        $acl->deny();

        // Add, one by one, access to resources for all roles
        $acl->allow('guest', \YourModule\Controller\YourController::class, ['action1', 'action2'], new \YourModule\Assertion\YourIdAssertion());

        return $acl;

    }

    public function getServiceLocator() {
        return $this->serviceLocator;
    }

    public function setServiceLocator(\Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) {
        $this->serviceLocator = $serviceLocator;
    }

}

Метод allow позволяет определить следующие параметры:

  • роль (обязательно)
  • ресурс (обязательно))
  • действия (необязательно)
  • класс утверждения (необязательно)

Наконец, после объявления, какие роли могут обращаться к конкретному действию определенного ресурса, вы также можетесообщить ACL «правило», например «получить доступ к действию, только если это условие выполнено».Эти правила указаны через Assertions:

use Zend\Permissions\Acl\Assertion\AssertionInterface;
use Zend\Permissions\Acl\Acl;
use Zend\Permissions\Acl\Role\RoleInterface as Role;
use Zend\Permissions\Acl\Resource\ResourceInterface as Resource;

class YourAssertion implements AssertionInterface {

    public function __construct($serviceManager) {
        // construct

    }

    public function assert(Acl $acl, Role $role = null, Resource $resource = null, $privilege = null) {
        $isAllowed = false;

        // Your logic to check if an user can access a specific id or not
        //  if(...){
        //      $isAllowed = true;
        //  }

        return $isAllowed;

    }

}

Надеюсь, это поможет вам!

...