vendor/symfony/security-core/Authentication/Provider/DaoAuthenticationProvider.php line 27

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Security\Core\Authentication\Provider;
  11. use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface;
  12. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  13. use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
  14. use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
  15. use Symfony\Component\Security\Core\Exception\BadCredentialsException;
  16. use Symfony\Component\Security\Core\Exception\UserNotFoundException;
  17. use Symfony\Component\Security\Core\User\LegacyPasswordAuthenticatedUserInterface;
  18. use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
  19. use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
  20. use Symfony\Component\Security\Core\User\UserCheckerInterface;
  21. use Symfony\Component\Security\Core\User\UserInterface;
  22. use Symfony\Component\Security\Core\User\UserProviderInterface;
  23. trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', DaoAuthenticationProvider::class);
  24. /**
  25. * DaoAuthenticationProvider uses a UserProviderInterface to retrieve the user
  26. * for a UsernamePasswordToken.
  27. *
  28. * @author Fabien Potencier <fabien@symfony.com>
  29. *
  30. * @deprecated since Symfony 5.3, use the new authenticator system instead
  31. */
  32. class DaoAuthenticationProvider extends UserAuthenticationProvider
  33. {
  34. private $hasherFactory;
  35. private $userProvider;
  36. /**
  37. * @param PasswordHasherFactoryInterface $hasherFactory
  38. */
  39. public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, string $providerKey, $hasherFactory, bool $hideUserNotFoundExceptions = true)
  40. {
  41. parent::__construct($userChecker, $providerKey, $hideUserNotFoundExceptions);
  42. if ($hasherFactory instanceof EncoderFactoryInterface) {
  43. trigger_deprecation('symfony/security-core', '5.3', 'Passing a "%s" instance to the "%s" constructor is deprecated, use "%s" instead.', EncoderFactoryInterface::class, __CLASS__, PasswordHasherFactoryInterface::class);
  44. }
  45. $this->hasherFactory = $hasherFactory;
  46. $this->userProvider = $userProvider;
  47. }
  48. /**
  49. * {@inheritdoc}
  50. */
  51. protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token)
  52. {
  53. $currentUser = $token->getUser();
  54. if ($currentUser instanceof UserInterface) {
  55. if ($currentUser->getPassword() !== $user->getPassword()) {
  56. throw new BadCredentialsException('The credentials were changed from another session.');
  57. }
  58. } else {
  59. if ('' === ($presentedPassword = $token->getCredentials())) {
  60. throw new BadCredentialsException('The presented password cannot be empty.');
  61. }
  62. if (null === $user->getPassword()) {
  63. throw new BadCredentialsException('The presented password is invalid.');
  64. }
  65. if (!$user instanceof PasswordAuthenticatedUserInterface) {
  66. trigger_deprecation('symfony/security-core', '5.3', 'Using password-based authentication listeners while not implementing "%s" interface from class "%s" is deprecated.', PasswordAuthenticatedUserInterface::class, get_debug_type($user));
  67. }
  68. $salt = $user->getSalt();
  69. if ($salt && !$user instanceof LegacyPasswordAuthenticatedUserInterface) {
  70. trigger_deprecation('symfony/security-core', '5.3', 'Returning a string from "getSalt()" without implementing the "%s" interface is deprecated, the "%s" class should implement it.', LegacyPasswordAuthenticatedUserInterface::class, get_debug_type($user));
  71. }
  72. // deprecated since Symfony 5.3
  73. if ($this->hasherFactory instanceof EncoderFactoryInterface) {
  74. $encoder = $this->hasherFactory->getEncoder($user);
  75. if (!$encoder->isPasswordValid($user->getPassword(), $presentedPassword, $salt)) {
  76. throw new BadCredentialsException('The presented password is invalid.');
  77. }
  78. if ($this->userProvider instanceof PasswordUpgraderInterface && method_exists($encoder, 'needsRehash') && $encoder->needsRehash($user->getPassword())) {
  79. $this->userProvider->upgradePassword($user, $encoder->encodePassword($presentedPassword, $user->getSalt()));
  80. }
  81. return;
  82. }
  83. $hasher = $this->hasherFactory->getPasswordHasher($user);
  84. if (!$hasher->verify($user->getPassword(), $presentedPassword, $salt)) {
  85. throw new BadCredentialsException('The presented password is invalid.');
  86. }
  87. if ($this->userProvider instanceof PasswordUpgraderInterface && $hasher->needsRehash($user->getPassword())) {
  88. $this->userProvider->upgradePassword($user, $hasher->hash($presentedPassword, $salt));
  89. }
  90. }
  91. }
  92. /**
  93. * {@inheritdoc}
  94. */
  95. protected function retrieveUser(string $userIdentifier, UsernamePasswordToken $token)
  96. {
  97. $user = $token->getUser();
  98. if ($user instanceof UserInterface) {
  99. return $user;
  100. }
  101. try {
  102. // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
  103. if (method_exists($this->userProvider, 'loadUserByIdentifier')) {
  104. $user = $this->userProvider->loadUserByIdentifier($userIdentifier);
  105. } else {
  106. trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
  107. $user = $this->userProvider->loadUserByUsername($userIdentifier);
  108. }
  109. if (!$user instanceof UserInterface) {
  110. throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
  111. }
  112. return $user;
  113. } catch (UserNotFoundException $e) {
  114. $e->setUserIdentifier($userIdentifier);
  115. throw $e;
  116. } catch (\Exception $e) {
  117. $e = new AuthenticationServiceException($e->getMessage(), 0, $e);
  118. $e->setToken($token);
  119. throw $e;
  120. }
  121. }
  122. }