8000 [Security] Allow custom user identifier for X509 authenticator · symfony/symfony@6479653 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6479653

Browse files
Spomkyfabpot
authored andcommitted
[Security] Allow custom user identifier for X509 authenticator
1 parent bb6e4da commit 6479653

File tree

4 files changed

+38
-4
lines changed

4 files changed

+38
-4
lines changed

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal
3636
->replaceArgument(2, $firewallName)
3737
->replaceArgument(3, $config['user'])
3838
->replaceArgument(4, $config['credentials'])
39+
->replaceArgument(6, $config['user_identifier'])
3940
;
4041

4142
return $authenticatorId;
@@ -58,6 +59,7 @@ public function addConfiguration(NodeDefinition $node)
5859
->scalarNode('provider')->end()
5960
->scalarNode('user')->defaultValue('SSL_CLIENT_S_DN_Email')->end()
6061
->scalarNode('credentials')->defaultValue('SSL_CLIENT_S_DN')->end()
62+
->scalarNode('user_identifier')->defaultValue('emailAddress')->end()
6163
->end()
6264
;
6365
}

src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
abstract_arg('user key'),
150150
abstract_arg('credentials key'),
151151
service('logger')->nullOnInvalid(),
152+
abstract_arg('credentials user identifier'),
152153
])
153154
->tag('monolog.logger', ['channel' => 'security'])
154155

src/Symfony/Component/Security/Http/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
{
8000
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;

src/Symfony/Component/Security/Http/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)
0