Каков наилучший способ уведомления пользователя после перенаправления правила access_control?

Из документов Symfony 2.3 Security :

Если доступ запрещен, система попытается аутентифицировать пользователя, если он еще не был (например, перенаправить пользователя на страницу входа) . Если пользователь уже вошел в систему, отобразится страница с ошибкой 403 «отказ от доступа». См. Раздел «Настройка страниц ошибок» для получения дополнительной информации.

В настоящее время я использую правило access_control для нескольких маршрутов. Я хотел бы уведомить анонимного пользователя, если они перенаправлены на маршрут входа в систему с таким сообщением, как « Вы должны войти в систему, чтобы получить доступ к этой странице ». Я несколько раз читал документы по безопасности и не нашел ничего подходящего для этого. Я что-то пропускаю?

Если нет, то каким образом можно было бы уведомить пользователя, когда они будут остановлены правилом access_control только если они перенаправлены на вход в систему (т. access_control Нет, если они просто неавторизированы )?

EDIT: Для уточнения, я специально спрашиваю, как проверить, было ли перенаправление вызвано правилом access_control (желательно, если возможно, на access_control ).

Solutions Collecting From Web of "Каков наилучший способ уведомления пользователя после перенаправления правила access_control?"

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

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


Код

security.yml:

 firewalls: main: entry_point: entry_point.user_login #or whatever you name your service pattern: ^/ form_login: # ... 

SRC / Acme / UserBundle / конфигурации / services.yml

 entry_point.user_login: class: Acme\UserBundle\Service\LoginEntryPoint arguments: [ @router ] #I am going to use this for URL generation since I will be redirecting in my service 

SRC / Acme / UserBundle / Услуги / LoginEntryPoint.php:

 namespace Acme\UserBundle\Service; use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface, Symfony\Component\Security\Core\Exception\AuthenticationException, Symfony\Component\HttpFoundation\Request, Symfony\Component\HttpFoundation\RedirectResponse; /** * When the user is not authenticated at all (ie when the security context has no token yet), * the firewall's entry point will be called to start() the authentication process. */ class LoginEntryPoint implements AuthenticationEntryPointInterface{ protected $router; public function __construct($router){ $this->router = $router; } /* * This method receives the current Request object and the exception by which the exception * listener was triggered. * * The method should return a Response object */ public function start(Request $request, AuthenticationException $authException = null){ $session = $request->getSession(); //I am choosing to set a FlashBag message with my own custom message. //Alternatively, you could use AuthenticaionException's generic message //by calling $authException->getMessage() $session->getFlashBag()->add('warning', 'You must be logged in to access that page'); return new RedirectResponse($this->router->generate('login')); } } 

login.html.twig:

 {# bootstrap ready for your convenience ;] #} {% if app.session.flashbag.has('warning') %} {% for flashMessage in app.session.flashbag.get('warning') %} <div class="alert alert-warning"> <button type="button" class="close" data-dismiss="alert">&times;</button> {{ flashMessage }} </div> {% endfor %} {% endif %} 

Ресурсы:

  • API аутентификацииEntryPointInterface
  • Документация о точках входа
  • Ссылка на конфигурацию безопасности
  • Как настроить вход в форму
  • Почему access_denied_handle не работает – благодаря cheesemacfly для подсказки

Я думаю, что прослушиватель kernel.exception и установка флеш-сообщения могут это сделать. Неподтвержденный пример:

 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; class My403ExceptionListener { protected $session; public function __construct(SessionInterface $session) { $this->session = $session; } public function onKernelException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); if ($exception instanceof AccessDeniedHttpException) { $this->session->getFlashBag()->set('warning', 'You must login to access that page.'); } } } 

Не знаю, работает ли это, или если это правильно. Вы можете зарегистрировать его как kernel.event_listener . Или, может быть, вам лучше разобраться с выделенным сервисом и установить его как параметр access_denied_handler в конфигурации брандмауэра . Я думаю, что существует множество возможных путей.

Могли бы вы не просто иметь два логина?

Например, в настройке конфигурации безопасности

 form_login: login_path: /login_message 

В контроллере входа в систему

 /** * @Template() * @Route("/notauthorized", name="login_message") */ public function loginMessageAction() { return []; } 

И затем в вашем loginMessage.html.twg

 <a href="{{ path('login') }}">You must login to access this page.</a>