vendor/symfony/security-http/Firewall/BasicAuthenticationListener.php line 25

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\Http\Firewall;
  11. use Psr\Log\LoggerInterface;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpKernel\Event\RequestEvent;
  14. use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
  15. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  16. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  17. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  18. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  19. use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
  20. use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
  21. trigger_deprecation('symfony/security-http''5.3''The "%s" class is deprecated, use the new authenticator system instead.'AnonymousAuthenticationListener::class);
  22. /**
  23.  * BasicAuthenticationListener implements Basic HTTP authentication.
  24.  *
  25.  * @author Fabien Potencier <fabien@symfony.com>
  26.  *
  27.  * @final
  28.  *
  29.  * @deprecated since Symfony 5.3, use the new authenticator system instead
  30.  */
  31. class BasicAuthenticationListener extends AbstractListener
  32. {
  33.     private $tokenStorage;
  34.     private $authenticationManager;
  35.     private $providerKey;
  36.     private $authenticationEntryPoint;
  37.     private $logger;
  38.     private $ignoreFailure;
  39.     private $sessionStrategy;
  40.     public function __construct(TokenStorageInterface $tokenStorageAuthenticationManagerInterface $authenticationManagerstring $providerKeyAuthenticationEntryPointInterface $authenticationEntryPointLoggerInterface $logger null)
  41.     {
  42.         if (empty($providerKey)) {
  43.             throw new \InvalidArgumentException('$providerKey must not be empty.');
  44.         }
  45.         $this->tokenStorage $tokenStorage;
  46.         $this->authenticationManager $authenticationManager;
  47.         $this->providerKey $providerKey;
  48.         $this->authenticationEntryPoint $authenticationEntryPoint;
  49.         $this->logger $logger;
  50.         $this->ignoreFailure false;
  51.     }
  52.     /**
  53.      * {@inheritdoc}
  54.      */
  55.     public function supports(Request $request): ?bool
  56.     {
  57.         return null !== $request->headers->get('PHP_AUTH_USER');
  58.     }
  59.     /**
  60.      * Handles basic authentication.
  61.      */
  62.     public function authenticate(RequestEvent $event)
  63.     {
  64.         $request $event->getRequest();
  65.         if (null === $username $request->headers->get('PHP_AUTH_USER')) {
  66.             return;
  67.         }
  68.         if (null !== $token $this->tokenStorage->getToken()) {
  69.             // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0
  70.             if ($token instanceof UsernamePasswordToken && $token->isAuthenticated(false) && (method_exists($token'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername()) === $username) {
  71.                 return;
  72.             }
  73.         }
  74.         if (null !== $this->logger) {
  75.             $this->logger->info('Basic authentication Authorization header found for user.', ['username' => $username]);
  76.         }
  77.         try {
  78.             $previousToken $token;
  79.             $token $this->authenticationManager->authenticate(new UsernamePasswordToken($username$request->headers->get('PHP_AUTH_PW'), $this->providerKey));
  80.             $this->migrateSession($request$token$previousToken);
  81.             $this->tokenStorage->setToken($token);
  82.         } catch (AuthenticationException $e) {
  83.             $token $this->tokenStorage->getToken();
  84.             if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getFirewallName()) {
  85.                 $this->tokenStorage->setToken(null);
  86.             }
  87.             if (null !== $this->logger) {
  88.                 $this->logger->info('Basic authentication failed for user.', ['username' => $username'exception' => $e]);
  89.             }
  90.             if ($this->ignoreFailure) {
  91.                 return;
  92.             }
  93.             $event->setResponse($this->authenticationEntryPoint->start($request$e));
  94.         }
  95.     }
  96.     /**
  97.      * Call this method if your authentication token is stored to a session.
  98.      *
  99.      * @final
  100.      */
  101.     public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyInterface $sessionStrategy)
  102.     {
  103.         $this->sessionStrategy $sessionStrategy;
  104.     }
  105.     private function migrateSession(Request $requestTokenInterface $token, ?TokenInterface $previousToken)
  106.     {
  107.         if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) {
  108.             return;
  109.         }
  110.         if ($previousToken) {
  111.             $user method_exists($token'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
  112.             $previousUser method_exists($previousToken'getUserIdentifier') ? $previousToken->getUserIdentifier() : $previousToken->getUsername();
  113.             if ('' !== ($user ?? '') && $user === $previousUser) {
  114.                 return;
  115.             }
  116.         }
  117.         $this->sessionStrategy->onAuthentication($request$token);
  118.     }
  119. }