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

130 Views Asked by At

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...
    }
2

There are 2 best solutions below

0
On BEST ANSWER

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.

7
On

You cannot deny access for logged in user to the login page by editing security.yml. It is all users of a Symfony app, whether logged in or not, will have the base access privilege: IS_AUTHENTICATED_ANONYMOUSLY and Symfony does not have a exclusive role to not logged in user.

However, you can achieve the same thing by checking whether the user has logged in or not in your controller and perform a redirect or throw an AccessDeniedException:

public function login($name, AuthorizationCheckerInterface $authChecker)
{
    if ($authChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
        throw new AccessDeniedException('Logged in user cannot access this page');
    }

    // ...
}