2013-07-02 2 views
18

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

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

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

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

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

ответ

53

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

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


Кодекс

безопасности.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 (i.e. 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 %} 

Ресурсы:

+2

ах здорово, спасибо за обмен – Kris

+5

Nice один Carrie, Какой кошмар! – Jimbo

+0

Хорошая работа. Сэкономил мне много времени! –

1

Я думаю, что 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 в firewall config. Я думаю, что существует множество возможных путей.

+0

access_denied_handler юг никогда не Уволен за переадресации, только несанкционированную –

+0

на правильном пути к этому служителю, проверьте мое решение –

+1

Entry Point, не должны написать это на моей шпаргалке ^^ –

-1

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

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

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> 
+1

может снизить и хотя эту возможность, я хочу специально искал и AET татуировки сделок с правилами access_control. Это временное решение, на самом деле не решение –

+0

Зонд да я вроде пояс у ипа AET Когда я написал. Примерно Sure Там Является «не хак» способ сделать это, им просто не проверить мой ответ Sure сут – Kris

+0

Hack-бесплатно для чистого раствора: D –

Смежные вопросы