vendor/contao/core-bundle/src/Security/Authentication/Token/TokenChecker.php line 75

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of Contao.
  5.  *
  6.  * (c) Leo Feyer
  7.  *
  8.  * @license LGPL-3.0-or-later
  9.  */
  10. namespace Contao\CoreBundle\Security\Authentication\Token;
  11. use Contao\BackendUser;
  12. use Contao\FrontendUser;
  13. use Symfony\Bundle\SecurityBundle\Security\FirewallConfig;
  14. use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
  15. use Symfony\Component\HttpFoundation\RequestStack;
  16. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  17. use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
  18. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  19. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  20. use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
  21. use Symfony\Component\Security\Http\FirewallMapInterface;
  22. class TokenChecker
  23. {
  24.     private const FRONTEND_FIREWALL 'contao_frontend';
  25.     private const BACKEND_FIREWALL 'contao_backend';
  26.     private RequestStack $requestStack;
  27.     private FirewallMapInterface $firewallMap;
  28.     private TokenStorageInterface $tokenStorage;
  29.     private SessionInterface $session;
  30.     private AuthenticationTrustResolverInterface $trustResolver;
  31.     private VoterInterface $roleVoter;
  32.     /**
  33.      * @internal Do not inherit from this class; decorate the "contao.security.token_checker" service instead
  34.      */
  35.     public function __construct(RequestStack $requestStackFirewallMapInterface $firewallMapTokenStorageInterface $tokenStorageSessionInterface $sessionAuthenticationTrustResolverInterface $trustResolverVoterInterface $roleVoter)
  36.     {
  37.         $this->requestStack $requestStack;
  38.         $this->firewallMap $firewallMap;
  39.         $this->tokenStorage $tokenStorage;
  40.         $this->session $session;
  41.         $this->trustResolver $trustResolver;
  42.         $this->roleVoter $roleVoter;
  43.     }
  44.     /**
  45.      * Checks if a front end user is authenticated.
  46.      */
  47.     public function hasFrontendUser(): bool
  48.     {
  49.         $token $this->getToken(self::FRONTEND_FIREWALL);
  50.         return null !== $token && VoterInterface::ACCESS_GRANTED === $this->roleVoter->vote($tokennull, ['ROLE_MEMBER']);
  51.     }
  52.     /**
  53.      * Checks if a back end user is authenticated.
  54.      */
  55.     public function hasBackendUser(): bool
  56.     {
  57.         $token $this->getToken(self::BACKEND_FIREWALL);
  58.         return null !== $token && VoterInterface::ACCESS_GRANTED === $this->roleVoter->vote($tokennull, ['ROLE_USER']);
  59.     }
  60.     /**
  61.      * Gets the front end username from the session.
  62.      */
  63.     public function getFrontendUsername(): ?string
  64.     {
  65.         $token $this->getToken(self::FRONTEND_FIREWALL);
  66.         if (null === $token || !$token->getUser() instanceof FrontendUser) {
  67.             return null;
  68.         }
  69.         return $token->getUser()->getUserIdentifier();
  70.     }
  71.     /**
  72.      * Gets the back end username from the session.
  73.      */
  74.     public function getBackendUsername(): ?string
  75.     {
  76.         $token $this->getToken(self::BACKEND_FIREWALL);
  77.         if (null === $token || !$token->getUser() instanceof BackendUser) {
  78.             return null;
  79.         }
  80.         return $token->getUser()->getUserIdentifier();
  81.     }
  82.     /**
  83.      * Tells whether the front end preview can show unpublished fragments.
  84.      */
  85.     public function isPreviewMode(): bool
  86.     {
  87.         $request $this->requestStack->getMainRequest();
  88.         if (null === $request || !$request->attributes->get('_preview'false)) {
  89.             return false;
  90.         }
  91.         $token $this->getToken(self::FRONTEND_FIREWALL);
  92.         return $token instanceof FrontendPreviewToken && $token->showUnpublished();
  93.     }
  94.     private function getToken(string $context): ?TokenInterface
  95.     {
  96.         $token $this->getTokenFromStorage($context);
  97.         if (null === $token) {
  98.             $token $this->getTokenFromSession('_security_'.$context);
  99.         }
  100.         if (!$token instanceof TokenInterface || !$token->isAuthenticated()) {
  101.             return null;
  102.         }
  103.         if ($this->trustResolver->isAnonymous($token)) {
  104.             return null;
  105.         }
  106.         return $token;
  107.     }
  108.     private function getTokenFromStorage(string $context): ?TokenInterface
  109.     {
  110.         $request $this->requestStack->getMainRequest();
  111.         if (!$this->firewallMap instanceof FirewallMap || null === $request) {
  112.             return null;
  113.         }
  114.         $config $this->firewallMap->getFirewallConfig($request);
  115.         if (!$config instanceof FirewallConfig || $config->getContext() !== $context) {
  116.             return null;
  117.         }
  118.         return $this->tokenStorage->getToken();
  119.     }
  120.     private function getTokenFromSession(string $sessionKey): ?TokenInterface
  121.     {
  122.         if (!$this->session->isStarted()) {
  123.             $request $this->requestStack->getMainRequest();
  124.             if (!$request || !$request->hasPreviousSession()) {
  125.                 return null;
  126.             }
  127.         }
  128.         // This will start the session if Request::hasPreviousSession() was true
  129.         if (!$this->session->has($sessionKey)) {
  130.             return null;
  131.         }
  132.         $token unserialize($this->session->get($sessionKey), ['allowed_classes' => true]);
  133.         if (!$token instanceof TokenInterface) {
  134.             return null;
  135.         }
  136.         return $token;
  137.     }
  138. }