bug #10749 Fixed incompatibility of x509 auth with nginx (alcaeus)
This PR was squashed before being merged into the 2.3 branch (closes #10749).
Discussion
----------
Fixed incompatibility of x509 auth with nginx
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
This commit fixes x509 authentication when using nginx as web server.
X509AuthenticationListener depends on the SSL_CLIENT_S_DN_Email field being set.
As is, this field is specific to Apache and cannot be provided by nginx. nginx
can provide the DN of the certificate in SSL_CLIENT_S_DN. If the email field is
not set, the listener tries to extract the email address from the DN.
Commits
-------
ba8fc16
Fixed incompatibility of x509 auth with nginx
This commit is contained in:
commit
4dcb158ba1
@ -41,10 +41,17 @@ class X509AuthenticationListener extends AbstractPreAuthenticatedListener
|
|||||||
*/
|
*/
|
||||||
protected function getPreAuthenticatedData(Request $request)
|
protected function getPreAuthenticatedData(Request $request)
|
||||||
{
|
{
|
||||||
if (!$request->server->has($this->userKey)) {
|
$user = null;
|
||||||
throw new BadCredentialsException(sprintf('SSL key was not found: %s', $this->userKey));
|
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, ''));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,7 @@ class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
|
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
|
||||||
|
|
||||||
$listener = new X509AuthenticationListener(
|
$listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey');
|
||||||
$context,
|
|
||||||
$authenticationManager,
|
|
||||||
'TheProviderKey'
|
|
||||||
);
|
|
||||||
|
|
||||||
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
|
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
|
||||||
$method->setAccessible(true);
|
$method->setAccessible(true);
|
||||||
@ -63,10 +59,39 @@ class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
|
||||||
*/
|
*/
|
||||||
public function testGetPreAuthenticatedDataNoUser()
|
public function testGetPreAuthenticatedDataNoData()
|
||||||
{
|
{
|
||||||
$request = new Request(array(), array(), array(), array(), array(), array());
|
$request = new Request(array(), array(), array(), array(), array(), array());
|
||||||
|
|
||||||
@ -74,11 +99,7 @@ class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
|
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
|
||||||
|
|
||||||
$listener = new X509AuthenticationListener(
|
$listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey');
|
||||||
$context,
|
|
||||||
$authenticationManager,
|
|
||||||
'TheProviderKey'
|
|
||||||
);
|
|
||||||
|
|
||||||
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
|
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
|
||||||
$method->setAccessible(true);
|
$method->setAccessible(true);
|
||||||
@ -98,13 +119,7 @@ class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
|
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
|
||||||
|
|
||||||
$listener = new X509AuthenticationListener(
|
$listener = new X509AuthenticationListener($context, $authenticationManager, 'TheProviderKey', 'TheUserKey', 'TheCredentialsKey');
|
||||||
$context,
|
|
||||||
$authenticationManager,
|
|
||||||
'TheProviderKey',
|
|
||||||
'TheUserKey',
|
|
||||||
'TheCredentialsKey'
|
|
||||||
);
|
|
||||||
|
|
||||||
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
|
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
|
||||||
$method->setAccessible(true);
|
$method->setAccessible(true);
|
||||||
|
Reference in New Issue
Block a user