phpauthenticationsymfonyweb-application-firewall

Symfony6 : App.User is null (Authenticated User is not saved) cause of token lost after redirection


I am working in Symfony5.3 application (released in 2020 or 2021 I guess), and I have to take it over and upgrade its version to Symfony6.2. Well, I am facing some problems during authentications, after calling app.user.username in my html.twig file I got : Impossible to access an attribute ("username") on a null variable. Well, i see app.user is null even after successful login, the User is not correctly set to app.

And I don't know what's missing, here is my code:

security.yaml

security:
    providers:
        database_users:
            id: App\Security\UsersProvider
    password_hashers:
        App\Entity\Users:
            algorithm: sha512
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: database_users
            logout:
                path: logout
                target: /login
                invalidate_session: true
            custom_authenticators:
                - App\Security\LoginFormAuthentificator

LoginForm

class LoginFormAuthentificator extends AbstractLoginFormAuthenticator 
    use TargetPathTrait;
    public const LOGIN_ROUTE = 'login';
    private $entityManager;
    private $urlGenerator;
    private $csrfTokenManager;
    private $userProvider;
    public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager,
     UserProviderInterface $userProvider)
    {
        $this->entityManager = $entityManager;
        $this->urlGenerator = $urlGenerator;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->userProvider = $userProvider;
    }
    ...
    ...
        public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): ?Response
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

        return new RedirectResponse($this->urlGenerator->generate('researchGeneral'));
    }

    public function authenticate(Request $request): \Symfony\Component\Security\Http\Authenticator\Passport\Passport {

        $encoder = new MessageDigestPasswordHasher('sha512', true, 5000);
        $user = $this->userProvider->loadUserByUsername($request->request->get("username"));
        if (!$user) {
            throw new CustomUserMessageAuthenticationException('Invalid credentials.');
        }

        $verif = $encoder->verify($user->getPassword(), $request->request->get("password"), 'sha512');
        if (!$verif) {
            throw new CustomUserMessageAuthenticationException('Invalid credentials.');
        }

        return new SelfValidatingPassport(new UserBadge($request->request->get("username")));
    }

SecurityController

class SecurityController extends AbstractController
{
    /**
     * @Route("/login", name="login")
     */
    public function login(AuthenticationUtils $authenticationUtils): Response
    {
        if ($this->getUser()) {
                return $this->redirectToRoute('researchGeneral');
        }

        // get the login error if there is one
        $error = $authenticationUtils->getLastAuthenticationError();
        // last username entered by the user
        $lastUsername = $authenticationUtils->getLastUsername();

        return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
    }

It's not the full code of each file, but I presented the code snippet I believe are concerned by this.

[EDIT] The exact problem is losing the access token after redirecting.


Solution

  • Well, after a lot of research, i found the problem, it was the method hasUserChanged in Symfony\Component\Security\Http\Firewall\ContextListener it detected an undesirable de-authentication because i've some mistakes on my userProvider.

    Anyway if you have encountered this problem, app.user null, or token changed after redirection is 100% due to malfunction of your components (provider or entity or security config or smth so) and it's really hard that someone can debug it for you.