1

Working with Symfony 4, and making an User environment (using SymfonyCast tutorials) I wrote a LoginFormAuthenticator :

class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
    use TargetPathTrait;

    private $entityManager;
    private $urlGenerator;
    private $csrfTokenManager;
    private $passwordEncoder;

    public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->entityManager = $entityManager;
        $this->urlGenerator = $urlGenerator;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->passwordEncoder = $passwordEncoder;
    }

    public function supports(Request $request)
    {
        return 'login' === $request->attributes->get('_route')
            && $request->isMethod('POST');
    }

    public function getCredentials(Request $request)
    {
        $credentials = [
            'username' => $request->request->get('username'),
            'password' => $request->request->get('password'),
            'csrf_token' => $request->request->get('_csrf_token'),
        ];
        $request->getSession()->set(
            Security::LAST_USERNAME,
            $credentials['username']
        );

        return $credentials;
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $token = new CsrfToken('authenticate', $credentials['csrf_token']);
        if (!$this->csrfTokenManager->isTokenValid($token)) {
            throw new InvalidCsrfTokenException();
        }

        $user = $this->entityManager->getRepository(User::class)->findOneBy(['username' => $credentials['username']]);
        if (!$user) {
            // fail authentication with a custom error
            throw new CustomUserMessageAuthenticationException('L\'username ne peut pas être trouvé.');
        }

        return $user;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

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

    protected function getLoginUrl()
    {
        return $this->urlGenerator->generate('login');
    }
}
`

But the issue is in the csrf protection. (after many searches, reducing the area of the issue) : I can't connect with my username, a loop give me always the form, with last username...

From the log :

[2019-11-16 15:27:17] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\Security\LoginFormAuthenticator"} [] [2019-11-16 15:27:17] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"App\Security\LoginFormAuthenticator"} []

Trying to better understand, I put a dd() in the getUser function :

$token = new CsrfToken('authenticate', $credentials['csrf_token']); dd($token);

and the result is :

LoginFormAuthenticator.php on line 63: CsrfToken^ {#345 ▼ -id: "authenticate" -value: "A11CgM6FtyduixvNmOotNkjqbakFCfYPD-TSXv8_PGE" }

We have a Csrf token. Searching more, I put in CsrfTokenManager (from Symfony/Security/Csrf) two dump() an a dd() in the istokenValid function :

    public function isTokenValid(CsrfToken $token)
{
    dump($token);
    $namespacedId = $this->getNamespace().$token->getId();
    dump($namespacedId);
    if (!$this->storage->hasToken($namespacedId)) {
    dd(!$this->storage->hasToken($namespacedId));
     return false;
    }

    return hash_equals($this->storage->getToken($namespacedId), $token->getValue());
}

and the results are :

CsrfTokenManager.php on line 109:

CsrfToken^ {#345 ▼ -id: "authenticate" -value: "YPZIzpw_8eU5Uy3YvV6PwySz4qz8FIz0EzkIwkBd-OQ" }

CsrfTokenManager.php on line 111:

"authenticate"

CsrfTokenManager.php on line 113:

true

So, if I understand well, we have a cookie, and the function return 'this cookie is not valid'...

What's wrong ?

1
  • Many thanks to @Albeis, who edited my post. I don't know if the issue is exactly the same, but I have observed that, trying to connect to the site (in prod environment) with diverse Ipad and Iphone, I can note exactly the same behavior : the process is interrupted, and return to the beginning of the login.
    – D.Picard
    Commented Nov 19, 2019 at 16:42

1 Answer 1

0

Eventually, we find our issue. With the great help of Ryan Weaver from SymfonyCast. Trying to manage the duration of the session, we have configured the handle_id and the cookie_path in framework.yaml ! And even if msDos and Linux accept it, AppleOs don't accept. That's all... :(

1
  • Do you have any link to Ryan suggestions that helped with this issue?
    – Manuel
    Commented Nov 25, 2020 at 11:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.