From ba8fc166cad8ead0cf27b44a6e5e10e41ad935ea Mon Sep 17 00:00:00 2001 From: alcaeus Date: Sun, 20 Apr 2014 13:12:50 +0200 Subject: [PATCH] Fixed incompatibility of x509 auth with nginx --- .../Firewall/X509AuthenticationListener.php | 13 +++-- .../X509AuthenticationListenerTest.php | 51 ++++++++++++------- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/Symfony/Component/Security/Http/Firewall/X509AuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/X509AuthenticationListener.php index 5aabf75fcf77..9c07be123481 100644 --- a/src/Symfony/Component/Security/Http/Firewall/X509AuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/X509AuthenticationListener.php @@ -41,10 +41,17 @@ public function __construct(SecurityContextInterface $securityContext, Authentic */ protected function getPreAuthenticatedData(Request $request) { - if (!$request->server->has($this->userKey)) { - throw new BadCredentialsException(sprintf('SSL key was not found: %s', $this->userKey)); + $user = null; + if ($request->server->has($this->userKey)) { + $user = $request->server->get($this->userKey); + } elseif ($request->server->has($this->credentialKey) && preg_match('#/emailAddress=(.+\@.+\..+)(/|$)#', $request->server->get($this->credentialKey), $matches)) { + $user = $matches[1]; } - return array($request->server->get($this->userKey), $request->server->get($this->credentialKey, '')); + if (null === $user) { + throw new BadCredentialsException(sprintf('SSL credentials not found: %s, %s', $this->userKey, $this->credentialKey)); + } + + return array($user, $request->server->get($this->credentialKey, '')); } } diff --git a/src/Symfony/Component/Security/Tests/Http/Firewall/X509AuthenticationListenerTest.php b/src/Symfony/Component/Security/Tests/Http/Firewall/X509AuthenticationListenerTest.php index c48aeac0a219..291f919b9172 100644 --- a/src/Symfony/Component/Security/Tests/Http/Firewall/X509AuthenticationListenerTest.php +++ b/src/Symfony/Component/Security/Tests/Http/Firewall/X509AuthenticationListenerTest.php @@ -42,11 +42,7 @@ public function testGetPreAuthenticatedData($user, $credentials) $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); - $listener = new X509AuthenticationListener( - $context, - $authenticationManager, - 'TheProviderKey' - ); + $listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey'); $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); $method->setAccessible(true); @@ -63,10 +59,39 @@ public static function dataProviderGetPreAuthenticatedData() ); } + /** + * @dataProvider dataProviderGetPreAuthenticatedDataNoUser + */ + public function testGetPreAuthenticatedDataNoUser($emailAddress) + { + $credentials = 'CN=Sample certificate DN/emailAddress='.$emailAddress; + $request = new Request(array(), array(), array(), array(), array(), array('SSL_CLIENT_S_DN' => $credentials)); + + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey'); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + $this->assertSame($result, array($emailAddress, $credentials)); + } + + public static function dataProviderGetPreAuthenticatedDataNoUser() + { + return array( + 'basicEmailAddress' => array('cert@example.com'), + 'emailAddressWithPlusSign' => array('cert+something@example.com'), + ); + } + /** * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException */ - public function testGetPreAuthenticatedDataNoUser() + public function testGetPreAuthenticatedDataNoData() { $request = new Request(array(), array(), array(), array(), array(), array()); @@ -74,11 +99,7 @@ public function testGetPreAuthenticatedDataNoUser() $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); - $listener = new X509AuthenticationListener( - $context, - $authenticationManager, - 'TheProviderKey' - ); + $listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey'); $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); $method->setAccessible(true); @@ -98,13 +119,7 @@ public function testGetPreAuthenticatedDataWithDifferentKeys() $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); - $listener = new X509AuthenticationListener( - $context, - $authenticationManager, - 'TheProviderKey', - 'TheUserKey', - 'TheCredentialsKey' - ); + $listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey', 'TheUserKey', 'TheCredentialsKey'); $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); $method->setAccessible(true);