vendor/kunstmaan/admin-bundle/EventListener/SessionSecurityListener.php line 81

Open in your IDE?
  1. <?php
  2. namespace Kunstmaan\AdminBundle\EventListener;
  3. use Psr\Log\LoggerInterface;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  6. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  7. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  8. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  9. use Symfony\Component\HttpKernel\HttpKernelInterface;
  10. class SessionSecurityListener
  11. {
  12.     /**
  13.      * @var LoggerInterface
  14.      */
  15.     private $logger;
  16.     /**
  17.      * @var bool
  18.      */
  19.     private $ipCheck;
  20.     /**
  21.      * @var bool
  22.      */
  23.     private $userAgentCheck;
  24.     /**
  25.      * @var string
  26.      */
  27.     private $ip;
  28.     /**
  29.      * @var string
  30.      */
  31.     private $userAgent;
  32.     /**
  33.      * @param bool            $ipCheck
  34.      * @param bool            $userAgentCheck
  35.      * @param LoggerInterface $logger
  36.      */
  37.     public function __construct($ipCheck$userAgentCheckLoggerInterface $logger)
  38.     {
  39.         $this->ipCheck $ipCheck;
  40.         $this->userAgentCheck $userAgentCheck;
  41.         $this->logger $logger;
  42.     }
  43.     /**
  44.      * @param FilterResponseEvent|ResponseEvent $event
  45.      */
  46.     public function onKernelResponse($event)
  47.     {
  48.         if (!$event instanceof FilterResponseEvent && !$event instanceof ResponseEvent) {
  49.             throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : FilterResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
  50.         }
  51.         if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
  52.             return;
  53.         }
  54.         // Make sure the ip and user agent is stored in the session
  55.         $request $event->getRequest();
  56.         if ($request->hasSession() && $request->getSession()->isStarted()) {
  57.             $session $request->getSession();
  58.             if ($this->ipCheck && !$session->has('kuma_ip')) {
  59.                 $session->set('kuma_ip'$this->getIp($request));
  60.             }
  61.             if ($this->userAgentCheck && !$session->has('kuma_ua')) {
  62.                 $session->set('kuma_ua'$this->getUserAgent($request));
  63.             }
  64.         }
  65.     }
  66.     /**
  67.      * @param GetResponseEvent $event
  68.      */
  69.     public function onKernelRequest(GetResponseEvent $event)
  70.     {
  71.         if (!$event instanceof GetResponseEvent && !$event instanceof ResponseEvent) {
  72.             throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
  73.         }
  74.         if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
  75.             return;
  76.         }
  77.         $request $event->getRequest();
  78.         if ($request->hasSession() && $request->getSession()->isStarted()) {
  79.             $session $request->getSession();
  80.             // Check that the ip matches
  81.             if ($this->ipCheck && $session->has('kuma_ip') && $session->get('kuma_ip') != $this->getIp($request)) {
  82.                 $this->logger->error(sprintf(
  83.                     "Session ip '%s' does not match with request ip '%s', invalidating the current session",
  84.                     $session->get('kuma_ip'),
  85.                     $this->getIp($request)
  86.                 ));
  87.                 $this->invalidateSession($session$request);
  88.             }
  89.             // Check that the user agent matches
  90.             if ($this->userAgentCheck && $session->has('kuma_ua') && $session->get('kuma_ua') != $this->getUserAgent($request)) {
  91.                 $this->logger->error(sprintf(
  92.                     "Session user agent '%s' does not match with request user agent '%s', invalidating the current session",
  93.                     $session->get('kuma_ua'),
  94.                     $this->getUserAgent($request)
  95.                 ));
  96.                 $this->invalidateSession($session$request);
  97.             }
  98.         }
  99.     }
  100.     /**
  101.      * @param SessionInterface $session
  102.      * @param Request          $request
  103.      */
  104.     private function invalidateSession(SessionInterface $sessionRequest $request)
  105.     {
  106.         $session->invalidate();
  107.         $session->set('kuma_ip'$this->getIp($request));
  108.         $session->set('kuma_ua'$this->getUserAgent($request));
  109.     }
  110.     /**
  111.      * @param Request $request
  112.      *
  113.      * @return string
  114.      */
  115.     private function getIp(Request $request)
  116.     {
  117.         if (!$this->ip) {
  118.             $forwarded $request->server->get('HTTP_X_FORWARDED_FOR');
  119.             if (\strlen($forwarded) > 0) {
  120.                 $parts explode(','$forwarded);
  121.                 $parts array_map('trim'$parts);
  122.                 $parts array_filter($parts);
  123.                 if (\count($parts) > 0) {
  124.                     $ip $parts[0];
  125.                 }
  126.             }
  127.             if (empty($ip)) {
  128.                 $ip $request->getClientIp();
  129.             }
  130.             $this->ip $ip;
  131.         }
  132.         return $this->ip;
  133.     }
  134.     /**
  135.      * @param Request $request
  136.      *
  137.      * @return array|string
  138.      */
  139.     private function getUserAgent(Request $request)
  140.     {
  141.         if (!$this->userAgent) {
  142.             $this->userAgent $request->headers->get('User-Agent');
  143.         }
  144.         return $this->userAgent;
  145.     }
  146. }