Skip to content

[Security] UserPasswordHasherInterface requires getSalt(), not on PasswordAuthenticatedUserInterface #41753

Closed
@dbrumann

Description

@dbrumann

Symfony version(s) affected: 5.3.2 (probably since 5.3.0)

Description
When using the UserPasswordHasherInterface with a User implementing the PasswordAuthenticatedUserInterface, but not the UserInterface you might run into the following error:

Attempted to call an undefined method named "getSalt" of class "<your user class>"

How to reproduce

  1. Create a user implementing the PasswordAuthenticatedUserInterface:

    namespace App\Entity;
    
    use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
    
    class User implements PasswordAuthenticatedUserInterface
    {
        private string $email;
        private string $password;
    
        public function __construct(
            private string $email,
            private string $password = '',
        ) {}
    
        public function getEmail(): string
        {
            return $this->email;
        }
    
        public function getPassword(): ?string
        {
            return $this->password;
        }
    
        public function updatePassword(string $hashedPassword): void
        {
            $this->password = $hashedPassword;
        }
    }
  2. Create a new user and call the password hasher:

    namespace App\Security;
    
    use App\Entity\User;
    use Doctrine\ORM\EntityManagerInterface;
    use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
    
    final class UserCreator
    {
        public function __construct(
            private EntityManagerInterface $entityManager,
            private UserPasswordHasherInterface $passwordHasher,
        ) {}
    
        public function create(string $name, string $password): void
        {
            $user = new User($name);
            $user->updatePassword($this->passwordHasher->hashPassword($user, $password));
    
            $this->entityManager->persist($user);
            $this->entityManager->flush();
            $this->entityManager->clear();
        }
    }

Actual Behavior
Fails at UserPasswordHasher#L46, because getSalt() does not exist

Expected Behavior
getSalt() should not be called, when the method is not provided.

Possible Solution
Use method_exists($user, 'getSalt') before calling the method.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions