phpsymfonysecurity

How to set access_control to disallow users having a 'ROLE_USER' to access path: ^/login after successful login?


In security.yaml file we define the access control for various routes and the ROLES who can access that same route.

But how can we set the user, who is logged-in but can't revisit the /login page unless and untill it logs out and "ROLE_USER" changes to "anon".

I am new to Symfony 4.2.

Controller:

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
//use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class SecurityController extends AbstractController
{
    /**
     * @Route("/login", name="login")
     */
    public function login(Request $request, AuthenticationUtils $utils, AuthorizationCheckerInterface $authChecker)
    {
        // to check whether user is looged-in
        if ($authChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
            die('Logged in user cannot access this page');
        }
        // get the login error if there is one
        $error = $utils->getLastAuthenticationError();

        // last username entered by the user
        $lastUsername = $utils->getLastUsername();
        return $this->render('security/login.html.twig', [
            'last_username' => $lastUsername,
            'error' => $error
            ]);
    }

    public function logout()
    {
        # code...
    }

Solution

  • As I mentioned in the comments, in my opinion throwing an AccessDeniedException to an already logged in user isn't a good approach. What would your users think? If I have already logged in, why can't I access a page, that I can normally access even if I'm not logged in.

    Therefore I'd strongly suggest to redirect logged in users, when accessing the /login path, to the start page of your application.

    Just adapt the if-condition block in the method login of your SecurityController:

    if ($authChecker->isGranted('IS_AUTHENTICATED_FULLY)) {
        $this->redirectToRoute('name of the route - replace with an appropriate value');
    }
    

    You should take care that the route you're redirecting to, doesn't cause another redirect and thus puts you in an endless loop.