vendor/pimcore/pimcore/bundles/AdminBundle/Security/Authenticator/AdminAbstractAuthenticator.php line 162

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\Security\Authenticator;
  15. use Pimcore\Bundle\AdminBundle\Security\Authentication\Token\TwoFactorRequiredToken;
  16. use Pimcore\Cache\RuntimeCache;
  17. use Pimcore\Model\User as UserModel;
  18. use Pimcore\Tool\Admin;
  19. use Pimcore\Tool\Authentication;
  20. use Pimcore\Tool\Session;
  21. use Psr\Log\LoggerAwareInterface;
  22. use Psr\Log\LoggerAwareTrait;
  23. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  24. use Symfony\Component\HttpFoundation\Cookie;
  25. use Symfony\Component\HttpFoundation\RedirectResponse;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
  29. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  30. use Symfony\Component\Routing\RouterInterface;
  31. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  32. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  33. use Symfony\Component\Security\Core\Exception\TooManyLoginAttemptsAuthenticationException;
  34. use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
  35. use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
  36. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  37. use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
  38. use Symfony\Contracts\Translation\TranslatorInterface;
  39. /**
  40.  * @internal
  41.  */
  42. abstract class AdminAbstractAuthenticator extends AbstractAuthenticator implements AuthenticatorInterfaceLoggerAwareInterface
  43. {
  44.     public const PIMCORE_ADMIN_LOGIN 'pimcore_admin_login';
  45.     public const PIMCORE_ADMIN_LOGIN_CHECK 'pimcore_admin_login_check';
  46.     use LoggerAwareTrait;
  47.     /**
  48.      * @var bool
  49.      */
  50.     protected $twoFactorRequired false;
  51.     public function __construct(
  52.         protected EventDispatcherInterface $dispatcher,
  53.         protected RouterInterface $router,
  54.         protected TranslatorInterface $translator
  55.     ) {
  56.     }
  57.     /**
  58.      * {@inheritdoc}
  59.      */
  60.     public function onAuthenticationFailure(Request $requestAuthenticationException $exception): ?Response
  61.     {
  62.         if ($exception instanceof TooManyLoginAttemptsAuthenticationException) {
  63.             throw new AccessDeniedHttpException(strtr($exception->getMessageKey(), $exception->getMessageData()));
  64.         }
  65.         $url $this->router->generate(AdminLoginAuthenticator::PIMCORE_ADMIN_LOGIN, [
  66.             'auth_failed' => 'true',
  67.         ]);
  68.         return new RedirectResponse($url);
  69.     }
  70.     /**
  71.      * {@inheritdoc}
  72.      */
  73.     public function onAuthenticationSuccess(Request $requestTokenInterface $token$providerKey): ?Response
  74.     {
  75.         /** @var UserModel $user */
  76.         $user $token->getUser()->getUser();
  77.         // set user language
  78.         $request->setLocale($user->getLanguage());
  79.         $this->translator->setLocale($user->getLanguage());
  80.         // set user on runtime cache for legacy compatibility
  81.         RuntimeCache::set('pimcore_admin_user'$user);
  82.         if ($user->isAdmin()) {
  83.             if (Admin::isMaintenanceModeScheduledForLogin()) {
  84.                 Admin::activateMaintenanceMode(Session::getSessionId());
  85.                 Admin::unscheduleMaintenanceModeOnLogin();
  86.             }
  87.         }
  88.         // as we authenticate statelessly (short lived sessions) the authentication is called for
  89.         // every request. therefore we only redirect if we're on the login page
  90.         if (!in_array($request->attributes->get('_route'), [
  91.             AdminLoginAuthenticator::PIMCORE_ADMIN_LOGIN,
  92.             AdminLoginAuthenticator::PIMCORE_ADMIN_LOGIN_CHECK,
  93.         ])) {
  94.             return null;
  95.         }
  96.         if ($request->get('deeplink') && $request->get('deeplink') !== 'true') {
  97.             $url $this->router->generate('pimcore_admin_login_deeplink');
  98.             $url .= '?' $request->get('deeplink');
  99.         } else {
  100.             $url $this->router->generate('pimcore_admin_index', [
  101.                 '_dc' => time(),
  102.                 'perspective' => strip_tags($request->get('perspective')),
  103.             ]);
  104.         }
  105.         if ($url) {
  106.             $response = new RedirectResponse($url);
  107.             $response->headers->setCookie(new Cookie('pimcore_admin_sid'true));
  108.             return $response;
  109.         }
  110.         return null;
  111.     }
  112.     /**
  113.      * @param $user
  114.      */
  115.     protected function saveUserToSession($user): void
  116.     {
  117.         if ($user && Authentication::isValidUser($user->getUser())) {
  118.             $pimcoreUser $user->getUser();
  119.             Session::useSession(function (AttributeBagInterface $adminSession) use ($pimcoreUser) {
  120.                 Session::regenerateId();
  121.                 $adminSession->set('user'$pimcoreUser);
  122.                 // this flag gets removed after successful authentication in \Pimcore\Bundle\AdminBundle\EventListener\TwoFactorListener
  123.                 if ($pimcoreUser->getTwoFactorAuthentication('required') && $pimcoreUser->getTwoFactorAuthentication('enabled')) {
  124.                     $adminSession->set('2fa_required'true);
  125.                 }
  126.             });
  127.         }
  128.     }
  129.     public function createToken(Passport $passportstring $firewallName): TokenInterface
  130.     {
  131.         if ($this->twoFactorRequired) {
  132.             return new TwoFactorRequiredToken(
  133.                 $passport->getUser(),
  134.                 $firewallName,
  135.                 $passport->getUser()->getRoles()
  136.             );
  137.         } else {
  138.             return parent::createToken($passport$firewallName);
  139.         }
  140.     }
  141.     /**
  142.      * @deprecated
  143.      */
  144.     public function createAuthenticatedToken(PassportInterface $passportstring $firewallName): TokenInterface
  145.     {
  146.         /** @var Passport $passport */
  147.         return $this->createToken($passport$firewallName);
  148.     }
  149. }