Использование Symfony2 AccessDeniedHandlerInterface

Я пытаюсь настроить свою настройку безопасности для symfony2, и у меня она работает до сих пор, но теперь мне нужно сделать еще несколько причудливых вещей. В настоящее время я использую все, что связано с PreAuthentication (я использую сторонний компонент для входа в систему и управления сеансом). Эта часть отлично работает в сочетании с комплектом безопасности JMS.

Теперь я к тому моменту, когда хочу поймать пользователей, которые бросают 403s, поэтому я могу просто переслать их на страницу входа стороннего компонента, который я использую. Я считаю, что лучше всего добавить обработчик исключений для прослушивателя исключений. Я смотрю AccessDeniedHandlerInterface.

  • Это правильное направление для меня?
  • Как добавить этот обработчик в прослушиватель исключений?

EDIT: В итоге я сделал что-то подобное. Я создал службу, которая запрашивается в событии kernel.exception. services.yml выглядит следующим образом:

services:
   kernel.listener.accessDenied:
    class: Fully\Qualified\Namespace\Path\To\Class
    tags:
      - { name: kernel.event_listener, event: kernel.exception, method: onAccessDeniedException }

и его класс:

<?php

namespace Fully\Qualified\Namespace\Path\To;

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent,
Symfony\Component\HttpFoundation\Response,
Symfony\Component\Security\Core\Exception\AccessDeniedException;

class Class
{
  public function onAccessDeniedException(GetResponseForExceptionEvent $event)
  {
    $exception = $event->getException();
    //Get the root cause of the exception.
    while (null !== $exception->getPrevious()) {
      $exception = $exception->getPrevious();
    }
    if ($exception instanceof AccessDeniedException) {
      //Forward to third-party.
    }
  }
}

Ответы

Ответ 1

Звучит правильно.

Или, если вас особенно интересует AccessDeniedException, вы также можете определить access_denied_handler в своем брандмауэре в security.yml:

security:
    firewalls:
        my_firewall:
            # ...
            access_denied_handler: kernel.listener.access_denied.handler
            # ...

Затем определите свою службу в своем services.xml или эквиваленте:

<parameters>
    <parameter key="kernel.listener.security.class">Path\To\Your\Class</parameter>
</parameters>

<service id="kernel.listener.access_denied.handler" class="%kernel.listener.security.class%">
    <tag name="kernel.event_listener" event="security.kernel_response" method="handle" />
</service>

Класс обработчика:

use \Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;

class MyAccessDeniedHandler implements AccessDeniedHandlerInterface
{
    public function handle(Request $request, AccessDeniedException $accessDeniedException)
    {
        // do something with your exception and return Response object (plain message of rendered template)
    }
}

Здесь вы можете найти полную ссылку на безопасность Symfony2: http://symfony.com/doc/2.8/reference/configuration/security.html