Skip to content

Commit 9624fb5

Browse files
Spomkyfabpot
authored andcommitted
[Security] Allow custom user identifier for X509 authenticator
1 parent 41b8631 commit 9624fb5

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

Authenticator/X509Authenticator.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@ class X509Authenticator extends AbstractPreAuthenticatedAuthenticator
3030
{
3131
private string $userKey;
3232
private string $credentialsKey;
33+
private string $credentialUserIdentifier;
3334

34-
public function __construct(UserProviderInterface $userProvider, TokenStorageInterface $tokenStorage, string $firewallName, string $userKey = 'SSL_CLIENT_S_DN_Email', string $credentialsKey = 'SSL_CLIENT_S_DN', LoggerInterface $logger = null)
35+
public function __construct(UserProviderInterface $userProvider, TokenStorageInterface $tokenStorage, string $firewallName, string $userKey = 'SSL_CLIENT_S_DN_Email', string $credentialsKey = 'SSL_CLIENT_S_DN', LoggerInterface $logger = null, string $credentialUserIdentifier = 'emailAddress')
3536
{
3637
parent::__construct($userProvider, $tokenStorage, $firewallName, $logger);
3738

3839
$this->userKey = $userKey;
3940
$this->credentialsKey = $credentialsKey;
41+
$this->credentialUserIdentifier = $credentialUserIdentifier;
4042
}
4143

4244
protected function extractUsername(Request $request): string
@@ -46,13 +48,13 @@ protected function extractUsername(Request $request): string
4648
$username = $request->server->get($this->userKey);
4749
} elseif (
4850
$request->server->has($this->credentialsKey)
49-
&& preg_match('#emailAddress=([^,/@]++@[^,/]++)#', $request->server->get($this->credentialsKey), $matches)
51+
&& preg_match('#'.preg_quote($this->credentialUserIdentifier, '#').'=([^,/]++)#', $request->server->get($this->credentialsKey), $matches)
5052
) {
51-
$username = $matches[1];
53+
$username = trim($matches[1]);
5254
}
5355

5456
if (null === $username) {
55-
throw new BadCredentialsException(sprintf('SSL credentials not found: %s, %s', $this->userKey, $this->credentialsKey));
57+
throw new BadCredentialsException(sprintf('SSL credentials not found: "%s", "%s".', $this->userKey, $this->credentialsKey));
5658
}
5759

5860
return $username;

Tests/Authenticator/X509AuthenticatorTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,35 @@ public function testAuthenticationCustomCredentialsKey()
120120
$this->assertEquals('cert@example.com', $passport->getUser()->getUserIdentifier());
121121
}
122122

123+
/**
124+
* @dataProvider provideServerVarsUserIdentifier
125+
*/
126+
public function testAuthenticationCustomCredentialsUserIdentifier($username, $credentials)
127+
{
128+
$authenticator = new X509Authenticator($this->userProvider, new TokenStorage(), 'main', 'SSL_CLIENT_S_DN_Email', 'SSL_CLIENT_S_DN', null, 'CN');
129+
130+
$request = $this->createRequest([
131+
'SSL_CLIENT_S_DN' => $credentials,
132+
]);
133+
$this->assertTrue($authenticator->supports($request));
134+
135+
$this->userProvider->createUser(new InMemoryUser($username, null));
136+
137+
$passport = $authenticator->authenticate($request);
138+
$this->assertEquals($username, $passport->getUser()->getUserIdentifier());
139+
}
140+
141+
public static function provideServerVarsUserIdentifier()
142+
{
143+
yield ['Sample certificate DN', 'CN=Sample certificate DN/emailAddress=cert@example.com'];
144+
yield ['Sample certificate DN', 'CN=Sample certificate DN/emailAddress=cert+something@example.com'];
145+
yield ['Sample certificate DN', 'CN=Sample certificate DN,emailAddress=cert@example.com'];
146+
yield ['Sample certificate DN', 'CN=Sample certificate DN,emailAddress=cert+something@example.com'];
147+
yield ['Sample certificate DN', 'emailAddress=cert+something@example.com,CN=Sample certificate DN'];
148+
yield ['Firstname.Lastname', 'emailAddress=firstname.lastname@mycompany.co.uk,CN=Firstname.Lastname,OU=london,OU=company design and engineering,OU=Issuer London,OU=Roaming,OU=Interactive,OU=Users,OU=Standard,OU=Business,DC=england,DC=core,DC=company,DC=co,DC=uk'];
149+
yield ['user1', 'C=FR, O=My Organization, CN=user1, emailAddress=user1@myorg.fr'];
150+
}
151+
123152
private function createRequest(array $server)
124153
{
125154
return new Request([], [], [], [], [], $server);

0 commit comments

Comments
 (0)