10000 [Security] UserPasswordHasherInterface requires getSalt(), not on PasswordAuthenticatedUserInterface · Issue #41753 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dbrumann opened this issue Jun 20, 2021 · 2 comments

Comments

@dbrumann
Copy link
Contributor
dbrumann commented Jun 20, 2021

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.

@stof
Copy link
Member
stof commented Jun 21, 2021

@wouterj is it expected that PasswordAuthenticatedUserInterface does not extend UserInterface ? this seems weird to me. The name of the interface makes me think that a PasswordAuthenticatedUserInterface is always expected to be a UserInterface

@chalasr
Copy link
Member
chalasr commented Jun 21, 2021

@stof Yes it is expected (I’m the author here) and I think it’s fine as is. PasswordAuthenticatedUserInterface could even be moved to password-hasher at some point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants
0