Bladeren bron

avoid fatal error on invalid session

Kris Wallsmith 12 jaren geleden
bovenliggende
commit
c51fc105f4

+ 15 - 8
src/Symfony/Component/Security/Http/Firewall/ContextListener.php

@@ -66,19 +66,26 @@ class ContextListener implements ListenerInterface
 
         if (null === $session || null === $token = $session->get('_security_'.$this->contextKey)) {
             $this->context->setToken(null);
-        } else {
-            if (null !== $this->logger) {
-                $this->logger->debug('Read SecurityContext from the session');
-            }
+            return;
+        }
 
-            $token = unserialize($token);
+        $token = unserialize($token);
 
-            if (null !== $token) {
-                $token = $this->refreshUser($token);
+        if (null !== $this->logger) {
+            $this->logger->debug('Read SecurityContext from the session');
+        }
+
+        if ($token instanceof TokenInterface) {
+            $token = $this->refreshUser($token);
+        } elseif (null !== $token) {
+            if (null !== $this->logger) {
+                $this->logger->warn(sprintf('Session includes a "%s" where a security token is expected', is_object($value) ? get_class($value) : gettype($value)));
             }
 
-            $this->context->setToken($token);
+            $token = null;
         }
+
+        $this->context->setToken($token);
     }
 
     /**

+ 61 - 0
tests/Symfony/Tests/Component/Security/Http/Firewall/ContextListenerTest.php

@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\Tests\Component\Security\Http\Firewall;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Http\Firewall\ContextListener;
+
+class ContextListenerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider provideInvalidToken
+     */
+    public function testInvalidTokenInSession($token)
+    {
+        $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+        $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+        $session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $event->expects($this->any())
+            ->method('getRequest')
+            ->will($this->returnValue($request));
+        $request->expects($this->any())
+            ->method('hasPreviousSession')
+            ->will($this->returnValue(true));
+        $request->expects($this->any())
+            ->method('getSession')
+            ->will($this->returnValue($session));
+        $session->expects($this->any())
+            ->method('get')
+            ->with('_security_key123')
+            ->will($this->returnValue(serialize($token)));
+        $context->expects($this->once())
+            ->method('setToken')
+            ->with(null);
+
+        $listener = new ContextListener($context, array(), 'key123');
+        $listener->handle($event);
+    }
+
+    public function provideInvalidToken()
+    {
+        return array(
+            array(new \__PHP_Incomplete_Class()),
+            array(null),
+        );
+    }
+}