vendor/pimcore/pimcore/bundles/AdminBundle/EventListener/AdminAuthenticationDoubleCheckListener.php line 90

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Bundle\AdminBundle\EventListener;
  15. use Pimcore\Bundle\AdminBundle\Controller\DoubleAuthenticationControllerInterface;
  16. use Pimcore\Bundle\AdminBundle\EventListener\Traits\ControllerTypeTrait;
  17. use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait;
  18. use Pimcore\Http\Request\Resolver\PimcoreContextResolver;
  19. use Pimcore\Http\RequestMatcherFactory;
  20. use Pimcore\Security\User\TokenStorageUserResolver;
  21. use Pimcore\Tool\Authentication;
  22. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  23. use Symfony\Component\HttpFoundation\Request;
  24. use Symfony\Component\HttpFoundation\RequestMatcherInterface;
  25. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  26. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  27. use Symfony\Component\HttpKernel\KernelEvents;
  28. /**
  29.  * Handles double authentication check for pimcore controllers after the firewall did to make sure the admin interface is
  30.  * not accessible on configuration errors. Unauthenticated routes are not double-checked (e.g. login).
  31.  *
  32.  * @internal
  33.  *
  34.  * @deprecated and will be removed in Pimcore 11.
  35.  */
  36. class AdminAuthenticationDoubleCheckListener implements EventSubscriberInterface
  37. {
  38.     use ControllerTypeTrait;
  39.     use PimcoreContextAwareTrait;
  40.     /**
  41.      * @var RequestMatcherFactory
  42.      */
  43.     protected $requestMatcherFactory;
  44.     /**
  45.      * @var array
  46.      */
  47.     protected $unauthenticatedRoutes;
  48.     /**
  49.      * @var RequestMatcherInterface[]
  50.      */
  51.     protected $unauthenticatedMatchers;
  52.     /**
  53.      * @var TokenStorageUserResolver
  54.      */
  55.     protected $tokenResolver;
  56.     /**
  57.      * @param RequestMatcherFactory $factory
  58.      * @param TokenStorageUserResolver $tokenResolver
  59.      * @param array $unauthenticatedRoutes
  60.      */
  61.     public function __construct(
  62.         RequestMatcherFactory $factory,
  63.         TokenStorageUserResolver $tokenResolver,
  64.         array $unauthenticatedRoutes
  65.     ) {
  66.         $this->requestMatcherFactory $factory;
  67.         $this->tokenResolver $tokenResolver;
  68.         $this->unauthenticatedRoutes $unauthenticatedRoutes;
  69.     }
  70.     /**
  71.      * {@inheritdoc}
  72.      */
  73.     public static function getSubscribedEvents(): array
  74.     {
  75.         return [
  76.             KernelEvents::CONTROLLER => 'onKernelController',
  77.         ];
  78.     }
  79.     public function onKernelController(ControllerEvent $event)
  80.     {
  81.         if (!$event->isMainRequest()) {
  82.             return;
  83.         }
  84.         $request $event->getRequest();
  85.         $isDoubleAuthController $this->isControllerType($eventDoubleAuthenticationControllerInterface::class);
  86.         $isPimcoreAdminContext $this->matchesPimcoreContext($requestPimcoreContextResolver::CONTEXT_ADMIN);
  87.         if (!$isDoubleAuthController && !$isPimcoreAdminContext) {
  88.             return;
  89.         }
  90.         // double check we have a valid user to make sure there is no invalid security config
  91.         // opening admin interface to the public
  92.         if ($this->requestNeedsAuthentication($request)) {
  93.             if ($isDoubleAuthController) {
  94.                 /** @var DoubleAuthenticationControllerInterface $controller */
  95.                 $controller $this->getControllerType($eventDoubleAuthenticationControllerInterface::class);
  96.                 if ($controller->needsSessionDoubleAuthenticationCheck()) {
  97.                     $this->checkSessionUser();
  98.                 }
  99.                 if ($controller->needsStorageDoubleAuthenticationCheck()) {
  100.                     $this->checkTokenStorageUser();
  101.                 }
  102.             } else {
  103.                 $this->checkSessionUser();
  104.                 $this->checkTokenStorageUser();
  105.             }
  106.         }
  107.     }
  108.     /**
  109.      * Check if the current request needs double authentication
  110.      *
  111.      * @param Request $request
  112.      *
  113.      * @return bool
  114.      */
  115.     protected function requestNeedsAuthentication(Request $request)
  116.     {
  117.         foreach ($this->getUnauthenticatedMatchers() as $matcher) {
  118.             if ($matcher->matches($request)) {
  119.                 return false;
  120.             }
  121.         }
  122.         return true;
  123.     }
  124.     /**
  125.      * Get list of paths which don't need double authentication check
  126.      *
  127.      * @return RequestMatcherInterface[]
  128.      */
  129.     protected function getUnauthenticatedMatchers()
  130.     {
  131.         if (null === $this->unauthenticatedMatchers) {
  132.             $this->unauthenticatedMatchers $this->requestMatcherFactory->buildRequestMatchers($this->unauthenticatedRoutes);
  133.         }
  134.         return $this->unauthenticatedMatchers;
  135.     }
  136.     /**
  137.      * @throws AccessDeniedHttpException
  138.      *      if there's no current user in the session
  139.      */
  140.     protected function checkSessionUser()
  141.     {
  142.         $user Authentication::authenticateSession();
  143.         if (null === $user) {
  144.             throw new AccessDeniedHttpException('User is invalid.');
  145.         }
  146.     }
  147.     /**
  148.      * @throws AccessDeniedHttpException
  149.      *      if there's no current user in the token storage
  150.      */
  151.     protected function checkTokenStorageUser()
  152.     {
  153.         $user $this->tokenResolver->getUser();
  154.         if (null === $user || !Authentication::isValidUser($user)) {
  155.             throw new AccessDeniedHttpException('User is invalid.');
  156.         }
  157.     }
  158. }