What is the best way to notify a user after an access_control rule redirects?

前端 未结 3 1099
庸人自扰
庸人自扰 2020-11-30 01:32

From Symfony 2.3 Security docs:

If access is denied, the system will try to authenticate the user if not already (e.g. redirect the user to th

3条回答
  •  暗喜
    暗喜 (楼主)
    2020-11-30 01:54

    So after quite a bit of research, I found the right way to do this. You'll need to use an Entry Point service and define it in your firewall configuration.

    This method will not mess with your default page settings specified in your firewall config for logging in.


    The Code

    security.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 AuthenticationException'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') %}
            
    {{ flashMessage }}
    {% endfor %} {% endif %}

    Resources:

    • AuthenticationEntryPointInterface API
    • Entry Points Documentation
    • Security Configuration Reference
    • How to Customize your Form Login
    • Why access_denied_handle doesn't work - thanks to cheesemacfly for tip

提交回复
热议问题