Quelle est la meilleure façon de notifier un utilisateur après une redirection d'une règle de contrôle d'accès?
à Partir de Symfony 2.3 Sécurité docs:
Si l'accès est refusé, , le système va tenter d'authentifier l'utilisateur si ce n'est déjà (par exemple, rediriger l'utilisateur vers la page de connexion) . Si l'utilisateur est déjà connecté, la 403 "accès refusé" page d'erreur sera affiché. Voir Comment personnaliser les Pages d'Erreur pour plus d'informations.
j'utilise actuellement une règle access_control
pour peu de routes. Je voudrais informer un utilisateur anonyme s'ils sont redirigés vers la route de connexion avec un message comme vous devez vous connecter pour accéder à cette page ."J'ai lu les documents de sécurité à quelques reprises et je n'ai rien trouvé de pertinent à ce sujet. Suis-je surplombant quelque chose?
si non, quelle serait la meilleure façon d'informer l'utilisateur quand il est arrêté par une access_control
règle seulement s'il est redirigé vers login (i.e. pas s'ils sont juste dans un rôle non autorisé )?
EDIT:
Pour clarifier, je demande spécifiquement comment vérifier si une redirection a été causée par une règle access_control
(de préférence en brindille si possible).
3 réponses
Alors, après un peu de recherche, j'ai trouvé la bonne façon de le faire. Vous devrez utiliser un service Entry Point et le définir dans votre configuration de pare-feu.
cette méthode ne modifiera pas avec votre page par défaut paramètres spécifiés dans votre configuration pare-feu pour la connexion.
Le Code
sécurité.yml:
firewalls:
main:
entry_point: entry_point.user_login #or whatever you name your service
pattern: ^/
form_login:
# ...
src/Acme/UserBundle/config/services.yml
services:
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.brindille:
{# 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">×</button>
{{ flashMessage }}
</div>
{% endfor %}
{% endif %}
ressources:
je pense qu'un kernel.exception
écouter et définir un message flash peut le faire. Exemple non testé:
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.');
}
}
}
Ne sais pas vraiment si ça fonctionne ou si c'est la bonne chose. Vous pouvez l'enregistrer comme kernel.event_listener
. Ou peut-être est-il préférable de choisir un service dédié et de le Définir comme paramètre de access_denied_handler
dans la firewall config . Je pense qu'il y a plusieurs façons possibles.
ne pourriez-vous pas simplement avoir deux itinéraires de connexion?
par exemple, dans la configuration de sécurité
form_login:
login_path: /login_message
dans votre contrôleur de connexion
/**
* @Template()
* @Route("/notauthorized", name="login_message")
*/
public function loginMessageAction()
{
return [];
}
et ensuite dans votre loginMessage.HTML.TGV
<a href="{{ path('login') }}">You must login to access this page.</a>