Как создать пользовательский обработчик отказа в доступе

Когда ваше приложение выдаёт AccessDeniedException, вы можете обработать это исключение с помощью сервиса, чтобы вернуть пользовательский ответ.

Для начала, создайте класс, реализующий AccessDeniedHandlerInterface. Этот интерфейс определяет один метод под названием handle(), в котором вы можете реализовать любую логику, которая должна быть выполнена, когда текущему пользователю будет отказано в доступе (например, отправка электронного письма, запись лога сообщения, или, чаще всего, возврат пользовательского ответа):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
namespace AppBundle\Security;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;

class AccessDeniedHandler implements AccessDeniedHandlerInterface
{
    public function handle(Request $request, AccessDeniedException $accessDeniedException)
    {
        // ...

        return new Response($content, 403);
    }
}

Если вы используете конфигурацию services.yml по умолчанию, то вы закончили! Symfony автоматически узнает о вашем новом сервисе. После этого вы можете сконфигурировать его под вашим брендмауэром:

  • YAML
    1
    2
    3
    4
    5
    6
    7
    # app/config/security.yml
    firewalls:
        # ...
    
        main:
            # ...
            access_denied_handler: AppBundle\Security\AccessDeniedHandler
    
  • XML
    1
    2
    3
    4
    5
    <config>
        <firewall name="main">
            <access_denied_handler>AppBundle\Security\AccessDeniedHandler</access_denied_handler>
        </firewall>
    </config>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    // app/config/security.php
    use AppBundle\Security\AccessDeniedHandler;
    
    $container->loadFromExtension('security', array(
        'firewalls' => array(
            'main' => array(
                // ...
                'access_denied_handler' => AccessDeniedHandler::class,
            ),
        ),
    ));
    

Вот и всё! Любой AccessDeniedException, выданный кодом под брендмауэром main теперь будет обработан вашим сервисом.

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.