src/ApiBundle/Security/Firewall/SessionAuthenticationListener.php line 33

Open in your IDE?
  1. <?php
  2. namespace ApiBundle\Security\Firewall;
  3. use Symfony\Component\DependencyInjection\ContainerInterface;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  6. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  7. use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
  8. use Symfony\Component\Security\Core\Exception\UserNotFoundException;
  9. use Symfony\Component\Security\Core\User\UserInterface;
  10. use Symfony\Component\Security\Core\User\UserProviderInterface;
  11. use Symfony\Component\Security\Csrf\CsrfToken;
  12. class SessionAuthenticationListener extends BaseAuthenticationListener
  13. {
  14.     /**
  15.      * @var UserProviderInterface
  16.      */
  17.     private $userProvider;
  18.     public function __construct(ContainerInterface $containerUserProviderInterface $userProvider)
  19.     {
  20.         parent::__construct($container);
  21.         $this->userProvider $userProvider;
  22.     }
  23.     /**
  24.      * @TODO key写死了
  25.      */
  26.     private $sessionKey '_security_main';
  27.     public function handle(Request $request)
  28.     {
  29.         if (null !== $this->getTokenStorage()->getToken()) {
  30.             return;
  31.         }
  32.         $session $this->container->get('session');
  33.         if (null === $session || null === $token $session->get($this->sessionKey)) {
  34.             return;
  35.         }
  36.         $this->isApiRequest($request) ?: $this->validateCsrfToken($request);
  37.         $token unserialize($token);
  38.         if ($token instanceof TokenInterface) {
  39.             $token $this->refreshUser($token);
  40.         } elseif (null !== $token) {
  41.             $token null;
  42.         }
  43.         $this->getTokenStorage()->setToken($token);
  44.     }
  45.     private function isApiRequest(Request $request)
  46.     {
  47.         return 'application/vnd.edusoho.v2+json' === $request->headers->get('Accept''') || 'application/vnd.edusoho.v3+json' === $request->headers->get('Accept''');
  48.     }
  49.     private function validateCsrfToken(Request $request)
  50.     {
  51.         if ($request->isXmlHttpRequest()) {
  52.             $token $request->headers->get('X-CSRF-Token');
  53.         } else {
  54.             $token $request->request->get('_csrf_token''');
  55.         }
  56.         if (!$this->container->get('security.csrf.token_manager')->isTokenValid(new CsrfToken('site'$token))) {
  57.             throw new AccessDeniedHttpException('The page has expired, please resubmit.');
  58.         }
  59.     }
  60.     /**
  61.      * Refreshes the user by reloading it from the user provider.
  62.      *
  63.      * @return TokenInterface|null
  64.      *
  65.      * @throws \RuntimeException
  66.      */
  67.     protected function refreshUser(TokenInterface $token)
  68.     {
  69.         $user $token->getUser();
  70.         if (!$user instanceof UserInterface) {
  71.             return $token;
  72.         }
  73.         try {
  74.             $refreshedUser $this->userProvider->refreshUser($user);
  75.             $token->setUser($refreshedUser);
  76.             return $token;
  77.         } catch (UnsupportedUserException $e) {
  78.             // let's try the next user provider
  79.         } catch (UserNotFoundException $e) {
  80.             return null;
  81.         }
  82.         throw new \RuntimeException(sprintf('There is no user provider for user "%s".'get_class($user)));
  83.     }
  84. }