简体   繁体   中英

How can I redirect logged in user in Symfony2 when he visits the login page?

I need to redirect a user when he visits the login page being already logged. I found some question, however the propose solution doesn't work for me. Here is the original question: Redirect already logged in user Symfony2

It doesn't work for me producing AuthenticationCredentialsNotFoundException .

Here is my firewall configuration:

firewalls:
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false

    login:
        pattern:  ^/secured/login$
        security: false

    password_reset:
        pattern:  ^/secured/login\-password/
        security: false

    secured_area:
        pattern:    ^/secured/
        form_login:
            check_path: /secured/login_check
            login_path: /secured/login
            default_target_path: /secured/app
            #provider: chain_provider
            provider: user_db
            success_handler: acme.security.authentication.success_handler
            failure_handler: acme.security.authentication.failure_handler
        logout:
            path:   /secured/logout
            target: /secured/login
        remember_me:
            key:      "%secret%"
            lifetime: 31536000 # 365 days in seconds
            path:     /
            domain:   ~ # Defaults to the current domain from $_SERVER

The proposed solution in the question I mentioned leads to the following exception:

AuthenticationCredentialsNotFoundException: The security context contains no authentication token. One possible reason may be that there is no firewall configured for this URL.

What am I doing wrong and how to solve this problem?

Here is my solution. As I don't have access to the token through API, I decided to take it from Session and pass (if found) and pass unserialized value to the access decision manager (that is normally used internally in the security context). Maybe there can be a better solution, but at least this will work till the moment when the better one will become evident.

<?php

namespace Acme\Bundle\Bundle\EventListener;

use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;

class LoggedInListener
{
    const APP_URL = 'acme_secured_app';
    const LOGIN_URL = 'acme_secured_login';

    private $router;
    private $decisionManager;

    /**
     * @param Router $router
     * @param AccessDecisionManagerInterface $decisionManager
     */
    public function __construct(Router $router, AccessDecisionManagerInterface $decisionManager)
    {
        $this->router = $router;
        $this->decisionManager = $decisionManager;
    }

    /**
     * @param GetResponseEvent $event
     */
    public function onKernelRequest(GetResponseEvent $event)
    {
        $firewallName = 'secured_area';
        $tokenStr = $event->getRequest()->getSession()->get('_security_'.$firewallName);
        if (!$tokenStr) {
            return;
        }
        $token = unserialize($tokenStr);
        if (!$token) {
            return;
        }

        $authenticated = $this->decisionManager->decide($token, array('IS_AUTHENTICATED_FULLY'));

        if ($authenticated) {
            // authenticated (NON anonymous)
            $routeName = $event->getRequest()->attributes->get('_route');
            if ($routeName == self::LOGIN_URL) {
                $url = $this->router->generate(self::APP_URL);
                $event->setResponse(new RedirectResponse($url));
            }
        }
    }
}
?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM