Arhn - архитектура программирования

Захват события неудачного входа в систему в Symfony3

У меня это настроено в security.yml;

 failure_path:      /login

Это перенаправляет пользователя на страницу входа, если он не прошел проверку подлинности при попытке доступа к определенным URL-адресам, установленным в access_control, например.

access_control:
    - { path: ^/admin, role: ROLE_ADMIN }

Но я не могу зафиксировать это перенаправление.

Я пытался использовать службу для события security.authentication.failure, но это не работает

app.security.authentication_failure_event_listener:
    class: MemberBundle\Event\AuthenticationListener
    tags:
        - { name: kernel.event_listener, event: security.authentication.failure, method: onAuthenticationFailure }

Перенаправление по-прежнему происходит, и onAuthenticationFailure никогда не вызывается. Предположительно, потому что аутентификация явно не провалилась. Пользователь просто не вошел в систему и перенаправлен.

Причина в том, что я хочу дать другой ответ в зависимости от ожидаемого формата. Например, я хочу, чтобы html-запросы переходили на страницу входа, но запросы JSON должны возвращать действительный JSON, а не страницу формы входа в HTML.

Я чувствую, что FOSRestBundle может справиться с этим, но кажется излишним для этой относительно простой потребности. И это не веб-сайт RESTFul, поэтому мне не нужен этот пакет для этого?

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

app.exception_listener:
    class: AppBundle\EventListener\ExceptionListener
    tags:
        - { name: kernel.event_listener, event: kernel.exception }

Итак, как я могу всегда фиксировать событие перенаправления, которое происходит, когда failure_path установлено в security.yml?

18.12.2016

  • Можете ли вы дать мне отзыв о моем ответе? 19.12.2016
  • @gp_sflover еще нет, я еще не использовал его, и ваше последнее предложение я уже пробовал, как указано в моем исходном вопросе. 19.12.2016

Ответы:


1

Мой совет (также и на будущее): "создайте пользовательскую систему аутентификации с помощью Guard Гораздо проще и гибче/настраивается для обработки этих вещей (особенно, если это немного сложно со многими аутентификаторами, такими как facebook, twitter и т. д., и с активированной опцией «запомнить меня»...).

Но... как показано в конфигурации SecurityBundle (" security") вы можете установить параметр failure_handler для каждой системы входа в этот брандмауэр:

security:
    firewalls:
        your_firewall_name:
             form_login:
                 failure_handler: your_custom_failure_handler_service_name <-- THIS ONE

Затем вы можете создать службу, внедряющую необходимые зависимости для обработки того, что вам нужно, и возвращать другой ответ в зависимости от формата запроса.

ПРИМЕЧАНИЕ. Я не уверен, что вы можете добиться этого, создав прослушиватель для Ошибка события аутентификации безопасности, но вы можете попробовать.

19.12.2016
  • Это было полезно, но не совсем дало мне ответ. Я опубликовал новый ответ. 20.12.2016

  • 2

    Таким образом, ответ на этот вопрос лежит в тонком аспекте Symfony и исключении AccessDeniedException.

    В том, что исключение создается только на основе ваших элементов управления доступом, если текущему пользователю не разрешен доступ. Он не выбрасывается, если вы вообще не аутентифицированы.

    То же самое верно для любого вида ловушек сбоя аутентификации. Он вызывается только с какой-то ошибкой аутентификации, а не в том случае, если вы просто не вошли в систему и, следовательно, не разрешены.

    Это делается с помощью двух новых сервисов.

    app.exception_listener:
        class: AppBundle\EventListener\ExceptionListener
        tags:
            - { name: kernel.event_listener, event: kernel.exception }
    
    app.entry_point:
        class: AppBundle\EventListener\EntryPoint
        arguments: ["@router"]
    

    Первый фиксирует AccessDeniedException, как и следовало ожидать, когда вам отказано в доступе к ресурсу.

    class ExceptionListener
    {
        public function onKernelException(GetResponseForExceptionEvent $event)
        {
            $exception = $event->getException();
            do {
                if ($exception instanceof AccessDeniedException) {
                    $request = $event->getRequest();
                    if ('json' == $request->get("format") || $request->isXmlHttpRequest()) {
                        $json = new JsonResponse(["status" => 0, 'not_logged_in' => true, "msg" => "You must be logged in"]);
                        $event->setResponse($json);
                    }
                }
            } while (null !== $exception = $exception->getPrevious());
        }
    }
    

    Служба точки входа должна быть установлена ​​в security.yml, например

    security
        firewalls:
            main:
                entry_point: app.entry_point
    

    Этот класс обрабатывает запуск брандмауэра и перенаправление для аутентификации. Я проверяю наличие исключения, а затем проверяю формат XHR и json и соответствующим образом обрабатываю.

    /**
     * Returns a response that directs the user to authenticate.
     *
     * This is called when an anonymous request accesses a resource that
     * requires authentication. The job of this method is to return some
     * response that "helps" the user start into the authentication process.
     *
     * Examples:
     *  A) For a form login, you might redirect to the login page
     *      return new RedirectResponse('/login');
     *  B) For an API token authentication system, you return a 401 response
     *      return new Response('Auth header required', 401);
     *
     * @param Request                 $request       The request that resulted in an AuthenticationException
     * @param AuthenticationException $authException The exception that started the authentication process
     *
     * @return Response
     */
    class EntryPoint implements AuthenticationEntryPointInterface
    {
        /** @var  Router */
        protected $router;
    
        public function __construct(Router $router)
        {
            $this->router = $router;
        }
    
        public function start(Request $request, AuthenticationException $authException = null) {
            if($authException) {
                if('json' == $request->get("format") || $request->isXmlHttpRequest()) {
                    return new JsonResponse(["status" => 0, 'not_logged_in' => true, "msg" => "You must be logged in"]);
                }
            }
    
            return new RedirectResponse($this->router->generate("fos_user_security_login"));
        }
    }
    
    20.12.2016
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..