Darius.V
Darius.V

Reputation: 928

Why credentials are null when erase_credentials is false?

Symfony 5.3

security.yaml

security:
    ...
    erase_credentials: false

LoginListener.php

<?php

namespace App\EventListener;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

class LoginListener
{
    private $passwordHasherFactory;
    private $em;

    public function __construct(PasswordHasherFactoryInterface $passwordHasherFactory, EntityManagerInterface $em)
    {
        $this->passwordHasherFactory = $passwordHasherFactory;
        $this->em = $em;
    }

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $user = $event->getAuthenticationToken()->getUser();
        $token = $event->getAuthenticationToken();

        // Migrate the user to the new hashing algorithm if is using the legacy one
        if ($user->hasLegacyPassword()) {
            // Credentials can be retrieved thanks to the false value of
            // the erase_credentials parameter in security.yml
            $plainPassword = $token->getCredentials();
            file_put_contents('darius.txt', 'test'.$plainPassword, FILE_APPEND); // why null?

        }

        $token->eraseCredentials();
    }
}

https://symfony.com/doc/current/reference/configuration/security.html#erase-credentials

If true, the eraseCredentials() method of the user object is called after authentication.

So probably if false it should not erase? Why it is erasing? Password is received because login works. I just dissapears at some point.

Update

Question is why credentials are null before calling

$token->eraseCredentials();

Upvotes: 1

Views: 494

Answers (1)

Darius.V
Darius.V

Reputation: 928

Managed to install xdebug and found that when creating token the credentials are not set:

JsonLoginAuthenticator:

public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface
    {
        return new UsernamePasswordToken($passport->getUser(), null, $firewallName, $passport->getUser()->getRoles());
    }

UsernamePasswordToken:

public function __construct($user, $credentials, string $firewallName, array $roles = [])
    {
        parent::__construct($roles);

        if ('' === $firewallName) {
            throw new \InvalidArgumentException('$firewallName must not be empty.');
        }

        $this->setUser($user);
        $this->credentials = $credentials;
        $this->firewallName = $firewallName;

        parent::setAuthenticated(\count($roles) > 0);
    }

So I guess that is the problem - under security - firewall there is such setup:

main:
        lazy: true
        provider: app_user_provider
        logout:
            path: logout
            target: after_logout
        json_login:
            check_path: /login
        entry_point: App\Security\AuthenticationEntryPoint

So probably I have answered my question why there is no credentials. I am just missing now how do create new password hash for password on login, but that is probably for different question.

Upvotes: 0

Related Questions