AuthenticationProviderManager.php (4119B)
1 <?php 2 3 namespace PartKeepr\AuthBundle\Security\Authentication; 4 5 use Symfony\Component\EventDispatcher\EventDispatcherInterface; 6 use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; 7 use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; 8 use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 9 use Symfony\Component\Security\Core\AuthenticationEvents; 10 use Symfony\Component\Security\Core\Event\AuthenticationEvent; 11 use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent; 12 use Symfony\Component\Security\Core\Exception\AccountStatusException; 13 use Symfony\Component\Security\Core\Exception\AuthenticationException; 14 use Symfony\Component\Security\Core\Exception\ProviderNotFoundException; 15 16 /** 17 * Class AuthenticationProviderManager. 18 * 19 * Re-implementation of the Symfony AuthenticationProviderManager to store the authentication provider in 20 * a token property. 21 */ 22 class AuthenticationProviderManager implements AuthenticationManagerInterface 23 { 24 private $providers; 25 26 private $eraseCredentials; 27 28 /** 29 * @var EventDispatcherInterface 30 */ 31 private $eventDispatcher; 32 33 /** 34 * Constructor. 35 * 36 * @param AuthenticationProviderInterface[] $providers An array of AuthenticationProviderInterface instances 37 * @param bool $eraseCredentials Whether to erase credentials after authentication or not 38 * 39 * @throws \InvalidArgumentException 40 */ 41 public function __construct(array $providers, $eraseCredentials = true) 42 { 43 if (!$providers) { 44 throw new \InvalidArgumentException('You must at least add one authentication provider.'); 45 } 46 47 foreach ($providers as $provider) { 48 if (!$provider instanceof AuthenticationProviderInterface) { 49 throw new \InvalidArgumentException(sprintf( 50 'UserProvider "%s" must implement the AuthenticationProviderInterface.', 51 get_class($provider) 52 )); 53 } 54 } 55 56 $this->providers = $providers; 57 $this->eraseCredentials = (bool) $eraseCredentials; 58 } 59 60 public function setEventDispatcher(EventDispatcherInterface $dispatcher) 61 { 62 $this->eventDispatcher = $dispatcher; 63 } 64 65 /** 66 * {@inheritdoc} 67 */ 68 public function authenticate(TokenInterface $token) 69 { 70 $lastException = null; 71 $result = null; 72 73 foreach ($this->providers as $provider) { 74 if (!$provider->supports($token)) { 75 continue; 76 } 77 78 try { 79 $result = $provider->authenticate($token); 80 81 if (null !== $result) { 82 $result->setAttribute('provider', get_class($provider)); 83 break; 84 } 85 } catch (AccountStatusException $e) { 86 $e->setToken($token); 87 88 throw $e; 89 } catch (AuthenticationException $e) { 90 $lastException = $e; 91 } 92 } 93 94 if (null !== $result) { 95 if (true === $this->eraseCredentials) { 96 $result->eraseCredentials(); 97 } 98 99 if (null !== $this->eventDispatcher) { 100 $this->eventDispatcher->dispatch( 101 AuthenticationEvents::AUTHENTICATION_SUCCESS, 102 new AuthenticationEvent($result) 103 ); 104 } 105 106 return $result; 107 } 108 109 if (null === $lastException) { 110 $lastException = new ProviderNotFoundException(sprintf( 111 'No Authentication UserProvider found for token of class "%s".', 112 get_class($token) 113 )); 114 } 115 116 if (null !== $this->eventDispatcher) { 117 $this->eventDispatcher->dispatch( 118 AuthenticationEvents::AUTHENTICATION_FAILURE, 119 new AuthenticationFailureEvent($token, $lastException) 120 ); 121 } 122 123 $lastException->setToken($token); 124 125 throw $lastException; 126 } 127 }