vendor/symfony/security-core/Authentication/AuthenticationProviderManager.php line 78

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;
  11. use Symfony\Component\PasswordHasher\Exception\InvalidPasswordException;
  12. use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
  13. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  14. use Symfony\Component\Security\Core\AuthenticationEvents;
  15. use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
  16. use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
  17. use Symfony\Component\Security\Core\Exception\AccountStatusException;
  18. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  19. use Symfony\Component\Security\Core\Exception\BadCredentialsException;
  20. use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
  21. use Symfony\Component\Security\Core\User\UserInterface;
  22. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  23. trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', AuthenticationProviderManager::class);
  24. // Help opcache.preload discover always-needed symbols
  25. class_exists(AuthenticationEvents::class);
  26. class_exists(AuthenticationFailureEvent::class);
  27. class_exists(AuthenticationSuccessEvent::class);
  28. /**
  29. * AuthenticationProviderManager uses a list of AuthenticationProviderInterface
  30. * instances to authenticate a Token.
  31. *
  32. * @author Fabien Potencier <fabien@symfony.com>
  33. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  34. *
  35. * @deprecated since Symfony 5.3, use the new authenticator system instead
  36. */
  37. class AuthenticationProviderManager implements AuthenticationManagerInterface
  38. {
  39. private $providers;
  40. private $eraseCredentials;
  41. private $eventDispatcher;
  42. /**
  43. * @param iterable<mixed, AuthenticationProviderInterface> $providers An iterable with AuthenticationProviderInterface instances as values
  44. * @param bool $eraseCredentials Whether to erase credentials after authentication or not
  45. *
  46. * @throws \InvalidArgumentException
  47. */
  48. public function __construct(iterable $providers, bool $eraseCredentials = true)
  49. {
  50. if (!$providers) {
  51. throw new \InvalidArgumentException('You must at least add one authentication provider.');
  52. }
  53. $this->providers = $providers;
  54. $this->eraseCredentials = $eraseCredentials;
  55. }
  56. public function setEventDispatcher(EventDispatcherInterface $dispatcher)
  57. {
  58. $this->eventDispatcher = $dispatcher;
  59. }
  60. /**
  61. * {@inheritdoc}
  62. */
  63. public function authenticate(TokenInterface $token)
  64. {
  65. $lastException = null;
  66. $result = null;
  67. foreach ($this->providers as $provider) {
  68. if (!$provider instanceof AuthenticationProviderInterface) {
  69. throw new \InvalidArgumentException(sprintf('Provider "%s" must implement the AuthenticationProviderInterface.', get_debug_type($provider)));
  70. }
  71. if (!$provider->supports($token)) {
  72. continue;
  73. }
  74. try {
  75. $result = $provider->authenticate($token);
  76. if (null !== $result) {
  77. break;
  78. }
  79. } catch (AccountStatusException $e) {
  80. $lastException = $e;
  81. break;
  82. } catch (AuthenticationException $e) {
  83. $lastException = $e;
  84. } catch (InvalidPasswordException $e) {
  85. $lastException = new BadCredentialsException('Bad credentials.', 0, $e);
  86. }
  87. }
  88. if (null !== $result) {
  89. if (true === $this->eraseCredentials) {
  90. $result->eraseCredentials();
  91. }
  92. if (null !== $this->eventDispatcher) {
  93. $this->eventDispatcher->dispatch(new AuthenticationSuccessEvent($result), AuthenticationEvents::AUTHENTICATION_SUCCESS);
  94. }
  95. // @deprecated since Symfony 5.3
  96. if ($result->getUser() instanceof UserInterface && !method_exists($result->getUser(), 'getUserIdentifier')) {
  97. trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "getUserIdentifier(): string" in user class "%s" is deprecated. This method will replace "getUsername()" in Symfony 6.0.', get_debug_type($result->getUser()));
  98. }
  99. return $result;
  100. }
  101. if (null === $lastException) {
  102. $lastException = new ProviderNotFoundException(sprintf('No Authentication Provider found for token of class "%s".', \get_class($token)));
  103. }
  104. if (null !== $this->eventDispatcher) {
  105. $this->eventDispatcher->dispatch(new AuthenticationFailureEvent($token, $lastException), AuthenticationEvents::AUTHENTICATION_FAILURE);
  106. }
  107. $lastException->setToken($token);
  108. throw $lastException;
  109. }
  110. }