2013-07-02 10 views
18

Von Symfony 2.3 Security docs:Wie kann ein Benutzer am besten benachrichtigt werden, nachdem eine access_control-Regel umgeleitet wurde?

Wenn der Zugriff verweigert wird, versucht das System der Benutzer, wenn nicht bereits zu authentifizieren (zum Beispiel der Benutzer auf die Login-Seite umleiten). Wenn der Benutzer bereits angemeldet ist, wird die Fehlerseite 403 "Zugriff verweigert" angezeigt. Weitere Informationen finden Sie unter Anpassen von Fehlerseiten.

Ich verwende derzeit eine access_control Regel für ein paar Routen. Ich möchte einen anonymen Benutzer benachrichtigen, wenn er mit einer Nachricht wie "" an die Login-Route weitergeleitet wird. Sie müssen sich anmelden, um auf diese Seite zugreifen zu können.. " Ich habe die Sicherheitsdokumente ein paar Mal durchgelesen und habe nichts Relevantes gefunden. Übersehe ich etwas?

Wenn nicht, was der beste Weg wäre, um den Benutzer zu benachrichtigen, wenn sie von einem access_control Regel nur gestoppt sind, wenn sie umgeleitet sind einzuloggen (also nicht, wenn sie nur in einer nicht autorisierte Rolle sind)

EDIT: Zur Klarstellung, ich speziell bin zu fragen, wie zu überprüfen, ob eine Umleitung durch eine access_control Regel (vorzugsweise in Zweig wenn möglich) verursacht wurde.

Antwort

53

So nach ziemlich viel der Forschung fand ich den richtigen Weg, dies zu tun. Sie müssen einen Entry Point Dienst verwenden und ihn in Ihrer Firewall-Konfiguration definieren.

Diese Methode wird nicht verwirren mit Ihren default page in Ihrer Firewall-Konfiguration festgelegten Einstellungen für die Anmeldung.


Der Kodex

Sicherheit.yml:

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

src/Acme/UserBundle/config/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/Service/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 %} 

Ressourcen:

+2

ah cool, danke für die Freigabe – Kris

+5

Nice one Carrie, was für ein Albtraum! – Jimbo

+0

Gute Arbeit. Sparte mir viel Zeit! –

1

Ich denke, ein kernel.exception Listener und die Einstellung einer Flash-Nachricht kann es tun. Ungetestetes Beispiel:

Ich weiß nicht wirklich, ob es funktioniert oder ob es das Richtige ist. Sie können es als kernel.event_listener registrieren. Oder vielleicht ist es besser, einen dedizierten Dienst zu schreiben und ihn als Parameter von access_denied_handler in firewall config einzustellen. Ich denke da gibt es viele mögliche Wege.

+0

die access_denied_handler nie für Umleitungen abgefeuert wird, nicht autorisierte nur –

+0

dies auf dem richtigen Weg war, meine Lösung –

+1

Einstiegspunkt zu überprüfen, sollte dies auf meinem Spickzettel schreiben ^^ –

-1

Können Sie nicht nur zwei Login-Routen haben?

Zum Beispiel in der Sicherheitskonfigurations gesetzt

form_login: 
    login_path: /login_message 

in Ihrem Login-Controller

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

Und dann in Ihrem loginMessage.html.twg

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

einreichen, obwohl dies eine Möglichkeit ist, suche ich speziell nach einem Weg, der mit access_control Regeln beschäftigt. Dies ist ein Workaround, aber nicht wirklich eine Lösung –

+0

Ja, ich fühlte mich irgendwie genauso, als ich es schrieb. Ich bin mir sicher, dass es einen "nicht hackischen" Weg gibt, ich bin einfach nicht sicher, wie – Kris

+0

meine Antwort für eine saubere hack-freie Lösung überprüfen: D –

Verwandte Themen