AuthenticationProviderManager.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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\EventDispatcher\EventDispatcherInterface;
  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\AuthenticationEvent;
  16. use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
  17. use Symfony\Component\Security\Core\Exception\AccountStatusException;
  18. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  19. use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
  20. /**
  21. * AuthenticationProviderManager uses a list of AuthenticationProviderInterface
  22. * instances to authenticate a Token.
  23. *
  24. * @author Fabien Potencier <fabien@symfony.com>
  25. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  26. */
  27. class AuthenticationProviderManager implements AuthenticationManagerInterface
  28. {
  29. private $providers;
  30. private $eraseCredentials;
  31. private $eventDispatcher;
  32. /**
  33. * @param AuthenticationProviderInterface[] $providers An array of AuthenticationProviderInterface instances
  34. * @param bool $eraseCredentials Whether to erase credentials after authentication or not
  35. *
  36. * @throws \InvalidArgumentException
  37. */
  38. public function __construct(array $providers, $eraseCredentials = true)
  39. {
  40. if (!$providers) {
  41. throw new \InvalidArgumentException('You must at least add one authentication provider.');
  42. }
  43. foreach ($providers as $provider) {
  44. if (!$provider instanceof AuthenticationProviderInterface) {
  45. throw new \InvalidArgumentException(sprintf('Provider "%s" must implement the AuthenticationProviderInterface.', \get_class($provider)));
  46. }
  47. }
  48. $this->providers = $providers;
  49. $this->eraseCredentials = (bool) $eraseCredentials;
  50. }
  51. public function setEventDispatcher(EventDispatcherInterface $dispatcher)
  52. {
  53. $this->eventDispatcher = $dispatcher;
  54. }
  55. /**
  56. * {@inheritdoc}
  57. */
  58. public function authenticate(TokenInterface $token)
  59. {
  60. $lastException = null;
  61. $result = null;
  62. foreach ($this->providers as $provider) {
  63. if (!$provider->supports($token)) {
  64. continue;
  65. }
  66. try {
  67. $result = $provider->authenticate($token);
  68. if (null !== $result) {
  69. break;
  70. }
  71. } catch (AccountStatusException $e) {
  72. $lastException = $e;
  73. break;
  74. } catch (AuthenticationException $e) {
  75. $lastException = $e;
  76. }
  77. }
  78. if (null !== $result) {
  79. if (true === $this->eraseCredentials) {
  80. $result->eraseCredentials();
  81. }
  82. if (null !== $this->eventDispatcher) {
  83. $this->eventDispatcher->dispatch(AuthenticationEvents::AUTHENTICATION_SUCCESS, new AuthenticationEvent($result));
  84. }
  85. return $result;
  86. }
  87. if (null === $lastException) {
  88. $lastException = new ProviderNotFoundException(sprintf('No Authentication Provider found for token of class "%s".', \get_class($token)));
  89. }
  90. if (null !== $this->eventDispatcher) {
  91. $this->eventDispatcher->dispatch(AuthenticationEvents::AUTHENTICATION_FAILURE, new AuthenticationFailureEvent($token, $lastException));
  92. }
  93. $lastException->setToken($token);
  94. throw $lastException;
  95. }
  96. }