Forráskód Böngészése

merged branch Herzult/fixHttpBasicAuthEntryPoint (PR #1439)

Commits
-------

e43cd20 [Security] Fix http retry authentication entry point
cb3ad8b [Security] Fix http form authentication entry point
1dfb637 [Security] Fix http digest authentication entry point
920a209 [Security] Fix http basic authentication entry point

Discussion
----------

[Security] Fix the http authentication entry points and test them
Fabien Potencier 14 éve
szülő
commit
fc1808643f

+ 1 - 1
src/Symfony/Component/Security/Http/EntryPoint/BasicAuthenticationEntryPoint.php

@@ -34,7 +34,7 @@ class BasicAuthenticationEntryPoint implements AuthenticationEntryPointInterface
     {
         $response = new Response();
         $response->headers->set('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realmName));
-        $response->setStatusCode(401, $authException->getMessage());
+        $response->setStatusCode(401, $authException ? $authException->getMessage() : null);
 
         return $response;
     }

+ 1 - 1
src/Symfony/Component/Security/Http/EntryPoint/DigestAuthenticationEntryPoint.php

@@ -57,7 +57,7 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
 
         $response = new Response();
         $response->headers->set('WWW-Authenticate', $authenticateHeader);
-        $response->setStatusCode(401, $authException->getMessage());
+        $response->setStatusCode(401, $authException ? $authException->getMessage() : null);
 
         return $response;
     }

+ 1 - 1
src/Symfony/Component/Security/Http/EntryPoint/FormAuthenticationEntryPoint.php

@@ -51,7 +51,7 @@ class FormAuthenticationEntryPoint implements AuthenticationEntryPointInterface
     public function start(Request $request, AuthenticationException $authException = null)
     {
         if ($this->useForward) {
-            $path = $this->httpUtils->createRequest($request, $this->loginPath);
+            $subRequest = $this->httpUtils->createRequest($request, $this->loginPath);
 
             return $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
         }

+ 1 - 1
src/Symfony/Component/Security/Http/EntryPoint/RetryAuthenticationEntryPoint.php

@@ -40,7 +40,7 @@ class RetryAuthenticationEntryPoint implements AuthenticationEntryPointInterface
         $scheme = $request->isSecure() ? 'http' : 'https';
         if ('http' === $scheme && 80 != $this->httpPort) {
             $port = ':'.$this->httpPort;
-        } elseif ('https' === $scheme && 443 != $this->httpPort) {
+        } elseif ('https' === $scheme && 443 != $this->httpsPort) {
             $port = ':'.$this->httpsPort;
         } else {
             $port = '';

+ 36 - 0
tests/Symfony/Tests/Component/Security/Http/EntryPoint/BasicAuthenticationEntryPointTest.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace Symfony\Tests\Component\Security\Http\EntryPoint;
+
+use Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+
+class BasicAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
+{
+    public function testStart()
+    {
+        $request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+
+        $authException = new AuthenticationException('The exception message');
+
+        $entryPoint = new BasicAuthenticationEntryPoint('TheRealmName');
+        $response = $entryPoint->start($request, $authException);
+
+        $this->assertEquals('Basic realm="TheRealmName"', $response->headers->get('WWW-Authenticate'));
+        $this->assertEquals(401, $response->getStatusCode());
+        $this->assertAttributeEquals('The exception message', 'statusText', $response);
+    }
+
+    public function testStartWithoutAuthException()
+    {
+        $request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+
+        $entryPoint = new BasicAuthenticationEntryPoint('TheRealmName');
+
+        $response = $entryPoint->start($request);
+
+        $this->assertEquals('Basic realm="TheRealmName"', $response->headers->get('WWW-Authenticate'));
+        $this->assertEquals(401, $response->getStatusCode());
+        $this->assertAttributeEquals('Unauthorized', 'statusText', $response);
+    }
+}

+ 50 - 0
tests/Symfony/Tests/Component/Security/Http/EntryPoint/DigestAuthenticationEntryPointTest.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace Symfony\Tests\Component\Security\Http\EntryPoint;
+
+use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\Exception\NonceExpiredException;
+
+class DigestAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
+{
+    public function testStart()
+    {
+        $request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+
+        $authenticationException = new AuthenticationException('TheAuthenticationExceptionMessage');
+
+        $entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheKey');
+        $response = $entryPoint->start($request, $authenticationException);
+
+        $this->assertEquals(401, $response->getStatusCode());
+        $this->assertAttributeEquals('TheAuthenticationExceptionMessage', 'statusText', $response);
+        $this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}"$/', $response->headers->get('WWW-Authenticate'));
+    }
+
+    public function testStartWithNoException()
+    {
+        $request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+
+        $entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheKey');
+        $response = $entryPoint->start($request);
+
+        $this->assertEquals(401, $response->getStatusCode());
+        $this->assertAttributeEquals('Unauthorized', 'statusText', $response);
+        $this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}"$/', $response->headers->get('WWW-Authenticate'));
+    }
+
+    public function testStartWithNonceExpiredException()
+    {
+        $request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+
+        $nonceExpiredException = new NonceExpiredException('TheNonceExpiredExceptionMessage');
+
+        $entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheKey');
+        $response = $entryPoint->start($request, $nonceExpiredException);
+
+        $this->assertEquals(401, $response->getStatusCode());
+        $this->assertAttributeEquals('TheNonceExpiredExceptionMessage', 'statusText', $response);
+        $this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}", stale="true"$/', $response->headers->get('WWW-Authenticate'));
+    }
+}

+ 55 - 0
tests/Symfony/Tests/Component/Security/Http/EntryPoint/FormAuthenticationEntryPointTest.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace Symfony\Tests\Component\Security\Http\EntryPoint;
+
+use Symfony\Component\Security\Http\EntryPoint\FormAuthenticationEntryPoint;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+
+class FormAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
+{
+    public function testStart()
+    {
+        $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false);
+        $response = $this->getMock('Symfony\Component\HttpFoundation\Response');
+
+        $httpKernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
+        $httpUtils = $this->getMock('Symfony\Component\Security\Http\HttpUtils');
+        $httpUtils
+            ->expects($this->once())
+            ->method('createRedirectResponse')
+            ->with($this->equalTo($request), $this->equalTo('/the/login/path'))
+            ->will($this->returnValue($response))
+        ;
+
+        $entryPoint = new FormAuthenticationEntryPoint($httpKernel, $httpUtils, '/the/login/path', false);
+
+        $this->assertEquals($response, $entryPoint->start($request));
+    }
+
+    public function testStartWithUseForward()
+    {
+        $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false);
+        $subRequest = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false);
+        $response = $this->getMock('Symfony\Component\HttpFoundation\Response');
+
+        $httpUtils = $this->getMock('Symfony\Component\Security\Http\HttpUtils');
+        $httpUtils
+            ->expects($this->once())
+            ->method('createRequest')
+            ->with($this->equalTo($request), $this->equalTo('/the/login/path'))
+            ->will($this->returnValue($subRequest))
+        ;
+
+        $httpKernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
+        $httpKernel
+            ->expects($this->once())
+            ->method('handle')
+            ->with($this->equalTo($request), $this->equalTo(HttpKernelInterface::SUB_REQUEST))
+            ->will($this->returnValue($response))
+        ;
+
+        $entryPoint = new FormAuthenticationEntryPoint($httpKernel, $httpUtils, '/the/login/path', true);
+
+        $this->assertEquals($response, $entryPoint->start($request));
+    }
+}

+ 51 - 0
tests/Symfony/Tests/Component/Security/Http/EntryPoint/RetryAuthenticationEntryPointTest.php

@@ -0,0 +1,51 @@
+<?php
+
+namespace Symfony\Tests\Component\Security\Http\EntryPoint;
+
+use Symfony\Component\Security\Http\EntryPoint\RetryAuthenticationEntryPoint;
+use Symfony\Component\HttpFoundation\Request;
+
+class RetryAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider dataForStart
+     */
+    public function testStart($httpPort, $httpsPort, $request, $expectedUrl)
+    {
+        $entryPoint = new RetryAuthenticationEntryPoint($httpPort, $httpsPort);
+        $response = $entryPoint->start($request);
+
+        $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
+        $this->assertEquals($expectedUrl, $response->headers->get('Location'));
+    }
+
+    public function dataForStart()
+    {
+        return array(
+            array(
+                80,
+                443,
+                Request::create('http://localhost/foo/bar?baz=bat'),
+                'https://localhost/foo/bar?baz=bat'
+            ),
+            array(
+                80,
+                443,
+                Request::create('https://localhost/foo/bar?baz=bat'),
+                'http://localhost/foo/bar?baz=bat'
+            ),
+            array(
+                80,
+                123,
+                Request::create('http://localhost/foo/bar?baz=bat'),
+                'https://localhost:123/foo/bar?baz=bat'
+            ),
+            array(
+                8080,
+                443,
+                Request::create('https://localhost/foo/bar?baz=bat'),
+                'http://localhost:8080/foo/bar?baz=bat'
+            )
+        );
+    }
+}