10000 Use one AuthenticatorManager per firewall · symfony/symfony@44cc76f · GitHub
[go: up one dir, main page]

Skip to content

Commit 44cc76f

Browse files
committed
Use one AuthenticatorManager per firewall
1 parent 09bed16 commit 44cc76f

File tree

5 files changed

+95
-21
lines changed

5 files changed

+95
-21
lines changed

src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use Symfony\Component\Console\Application;
2424
use Symfony\Component\DependencyInjection\Alias;
2525
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
26+
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
2627
use Symfony\Component\DependencyInjection\ChildDefinition;
2728
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
2829
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -278,19 +279,16 @@ private function createFirewalls(array $config, ContainerBuilder $container)
278279
$mapDef->replaceArgument(0, ServiceLocatorTagPass::register($container, $contextRefs));
279280
$mapDef->replaceArgument(1, new IteratorArgument($map));
280281

281-
// add authentication providers to authentication manager
282-
$authenticationProviders = array_map(function ($id) {
283-
return new Reference($id);
284-
}, array_unique($authenticationProviders));
285-
$authenticationManagerId = 'security.authentication.manager.provider';
286-
if ($this->authenticatorManagerEnabled) {
287-
$authenticationManagerId = 'security.authentication.manager.authenticator';
288-
$container->setAlias('security.authentication.manager', new Alias($authenticationManagerId));
282+
if (!$this->authenticatorManagerEnabled) {
283+
// add authentication providers to authentication manager
284+
$authenticationProviders = array_map(function ($id) {
285+
return new Reference($id);
286+
}, array_unique($authenticationProviders));
287+
288+
$container
289+
->getDefinition('security.authentication.manager')
290+
->replaceArgument(0, new IteratorArgument($authenticationProviders));
289291
}
290-
$container
291-
->getDefinition($authenticationManagerId)
292-
->replaceArgument(0, new IteratorArgument($authenticationProviders))
293-
;
294292

295293
// register an autowire alias for the UserCheckerInterface if no custom user checker service is configured
296294
if (!$customUserChecker) {
@@ -441,17 +439,28 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
441439
$authenticationProviders = array_merge($authenticationProviders, $firewallAuthenticationProviders);
442440

443441
if ($this->authenticatorManagerEnabled) {
442+
// authenticator manager
443+
$authenticators = array_map(function ($id) {
444+
return new Reference($id);
445+
}, $firewallAuthenticationProviders);
446+
$container
447+
->setDefinition($managerId = 'security.authenticator.manager.'.$id, new ChildDefinition('security.authentication.manager.authenticator'))
448+
->replaceArgument(0, $authenticators)
449+
;
450+
451+
$managerLocator = $container->getDefinition('security.authenticator.managers_locator');
452+
$managerLocator->replaceArgument(0, array_merge($managerLocator->getArgument(0), [$id => new ServiceClosureArgument(new Reference($managerId))]));
453+
444454
// authenticator manager listener
445455
$container
446456
->setDefinition('security.firewall.authenticator.'.$id.'.locator', new ChildDefinition('security.firewall.authenticator.locator'))
447-
->setArguments([array_map(function ($id) {
448-
return new Reference($id);
449-
}, $firewallAuthenticationProviders)])
457+
->setArguments([$authenticators])
450458
->addTag('container.service_locator')
451459
;
452460

453461
$container
454462
->setDefinition('security.firewall.authenticator.'.$id, new ChildDefinition('security.firewall.authenticator'))
463+
->replaceArgument(0, new Reference($managerId))
455464
->replaceArgument(2, new Reference('security.firewall.authenticator.'.$id.'.locator'))
456465
->replaceArgument(3, $id)
457466
;

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,29 @@
66
<services>
77
<!-- Manager -->
88

9-
<service id="security.authentication.manager.authenticator" class="Symfony\Component\Security\Http\Authentication\AuthenticatorManager">
9+
<service id="security.authentication.manager.authenticator"
10+
class="Symfony\Component\Security\Http\Authentication\AuthenticatorManager"
11+
abstract="true"
12+
>
1013
<argument type="abstract">authenticators</argument>
1114
<argument type="service" id="event_dispatcher" />
1215
<argument>%security.authentication.manager.erase_credentials%</argument>
1316
<call method="setEventDispatcher">
1417
<argument type="service" id="event_dispatcher" />
1518
</call>
1619
</service>
20+
21+
<service id="security.authenticator.managers_locator"
22+
class="Symfony\Component\DependencyInjection\ServiceLocator">
23+
<argument type="collection" />
24+
</service>
25+
26+
<service id="security.authentication.manager"
27+
class="Symfony\Bundle\SecurityBundle\Security\FirewallAwareAuthenticatorManager">
28+
<argument type="service" id="security.firewall.map" />
29+
<argument type="service" id="security.authenticator.managers_locator" />
30+
<argument type="service" id="request_stack" />
31+
</service>
1732
<service id="Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface" alias="security.authentication.manager" />
1833

1934
<service id="security.authenticator_handler"
@@ -35,7 +50,7 @@
3550
class="Symfony\Bundle\SecurityBundle\EventListener\LazyAuthenticatorManagerListener"
3651
abstract="true">
3752
<tag name="monolog.logger" channel="security" />
38-
<argument type="service" id="security.authentication.manager" />
53+
<argument type="abstract">authenticator manager</argument>
3954
<argument type="service" id="security.authenticator_handler" />
4055
<argument/> <!-- authenticator locator -->
4156
<argument/> <!-- provider key -->
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Security;
13+
14+
use Symfony\Component\DependencyInjection\ServiceLocator;
15+
use Symfony\Component\HttpFoundation\RequestStack;
16+
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
17+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
18+
use Symfony\Component\Security\Core\Exception\LogicException;
19+
20+
/**
21+
* A decorator that delegates all method calls to the authenticator
22+
* manager of the current firewall.
23+
*
24+
* @author Wouter de Jong <wouter@wouterj.nl>
25+
*/
26+
class FirewallAwareAuthenticatorManager implements AuthenticationManagerInterface
27+
{
28+
private $firewallMap;
29+
private $authenticatorManagers;
30+
private $requestStack;
31+
32+
public function __construct(FirewallMap $firewallMap, ServiceLocator $authenticatorManagers, RequestStack $requestStack)
33+
{
34+
$this->firewallMap = $firewallMap;
35+
$this->authenticatorManagers = $authenticatorManagers;
36+
$this->requestStack = $requestStack;
37+
}
38+
39+
public function authenticate(TokenInterface $token)
40+
{
41+
$firewallConfig = $this->firewallMap->getFirewallConfig($this->requestStack->getMasterRequest());
42+
if (null === $firewallConfig) {
43+
throw new LogicException('Cannot call authenticate on this request, as it is not behind a firewall.');
44+
}
45+
46+
return $this->authenticatorManagers->get($firewallConfig->getName())->authenticate($token);
47+
}
48+
}

src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,16 @@ class AuthenticatorManager implements AuthenticationManagerInterface
4040
private $authenticators;
4141
private $eventDispatcher;
4242
private $eraseCredentials;
43+
private $providerKey;
4344

4445
/**
4546
* @param AuthenticatorInterface[] $authenticators The authenticators, with keys that match what's passed to AuthenticatorManagerListener
4647
*/
47-
public function __construct(iterable $authenticators, EventDispatcherInterface $eventDispatcher, bool $eraseCredentials = true)
48+
public function __construct(iterable $authenticators, EventDispatcherInterface $eventDispatcher, string $providerKey, bool $eraseCredentials = true)
4849
{
4950
$this->authenticators = $authenticators;
5051
$this->eventDispatcher = $eventDispatcher;
52+
$this->providerKey = $providerKey;
5153
$this->eraseCredentials = $eraseCredentials;
5254
}
5355

src/Symfony/Component/Security/Http/Firewall/AuthenticatorManagerListener.php

Lines changed: 3 additions & 3 deletions
2851
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
*/
3434
class AuthenticatorManagerListener extends AbstractListener
3535
{
36-
private $authenticationManager;
36+
private $authenticatorManager;
3737
private $authenticatorHandler;
3838
private $authenticators;
3939
protected $providerKey;
@@ -45,7 +45,7 @@ class AuthenticatorManagerListener extends AbstractListener
4545
*/
4646
public function __construct(AuthenticationManagerInterface $authenticationManager, AuthenticatorHandler $authenticatorHandler, iterable $authenticators, string $providerKey, EventDispatcherInterface $eventDispatcher, ?LoggerInterface $logger = null)
4747
{
48-
$this->authenticationManager = $authenticationManager;
48+
$this->authenticatorManager = $authenticationManager;
4949
$this->authenticatorHandler = $authenticatorHandler;
5050
$this->authenticators = $authenticators;
5151
$this->providerKey = $providerKey;
@@ -157,7 +157,7 @@ private function executeAuthenticator(string $uniqueAuthenticatorKey, Authentica
157157
}
158158
// pass the token into the AuthenticationManager system
159159
// this indirectly calls AuthenticatorManager::authenticate()
160-
$token = $this->authenticationManager->authenticate($token);
160+
$token = $this->authenticatorManager->authenticate($token);
161161

162162
if (null !== $this->logger) {
163163
$this->logger->info('Authenticator successful!', ['token' => $token, 'authenticator' => \get_class($authenticator)]);

0 commit comments

Comments
 (0)
0