Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8960e3a

Browse files
committed
Integrated GuardAuthenticationManager in the FrameworkBundle
1 parent 80b205e commit 8960e3a

File tree

6 files changed

+122
-21
lines changed

6 files changed

+122
-21
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public function getConfigTreeBuilder()
7474
->booleanNode('hide_user_not_found')->defaultTrue()->end()
7575
->booleanNode('always_authenticate_before_granting')->defaultFalse()->end()
7676
->booleanNode('erase_credentials')->defaultTrue()->end()
77+
->booleanNode('guard_authentication_manager')->defaultFalse()->end()
7778
->arrayNode('access_decision_manager')
7879
->addDefaultsIfNotSet()
7980
->children()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\DependencyInjection\Security\Factory;
13+
14+
use Symfony\Component\DependencyInjection\ContainerBuilder;
15+
16+
/**
17+
* @author Wouter de Jong <[email protected]>
18+
*/
19+
interface GuardFactoryInterface
20+
{
21+
/**
22+
* Creates the Guard service for the provided configuration.
23+
*
24+
* @return string The Guard service ID to be used by the firewall
25+
*/
26+
public function createGuard(ContainerBuilder $container, string $id, array $config, string $userProviderId): string;
27+
}

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*
2222
* @author Fabien Potencier <[email protected]>
2323
*/
24-
class HttpBasicFactory implements SecurityFactoryInterface
24+
class HttpBasicFactory implements SecurityFactoryInterface, GuardFactoryInterface
2525
{
2626
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
2727
{
@@ -46,6 +46,17 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider,
4646
return [$provider, $listenerId, $entryPointId];
4747
}
4848

49+
public function createGuard(ContainerBuilder $container, string $id, array $config, string $userProviderId): string
50+
{
51+
$authenticatorId = 'security.authenticator.basic.'.$id;
52+
$container
53+
->setDefinition($authenticatorId, new ChildDefinition('security.authenticator.basic'))
54+
->replaceArgument(0, $config['realm'])
55+
->replaceArgument(1, new Reference($userProviderId));
56+
57+
return $authenticatorId;
58+
}
59+
4960
public function getPosition()
5061
{
5162
return 'http';

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

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\SecurityBundle\DependencyInjection;
1313

14+
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\GuardFactoryInterface;
1415
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\RememberMeFactory;
1516
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
1617
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface;
@@ -53,6 +54,8 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
5354
private $userProviderFactories = [];
5455
private $statelessFirewallKeys = [];
5556

57+
private $guardAuthenticationManagerEnabled = false;
58+
5659
public function __construct()
5760
{
5861
foreach ($this->listenerPositions as $position) {
@@ -140,6 +143,8 @@ public function load(array $configs, ContainerBuilder $container)
140143
$container->setParameter('security.access.always_authenticate_before_granting', $config['always_authenticate_before_granting']);
141144
$container->setParameter('security.authentication.hide_user_not_found', $config['hide_user_not_found']);
142145

146+
$this->guardAuthenticationManagerEnabled = $config['guard_authentication_manager'];
147+
143148
$this->createFirewalls($config, $container);
144149
$this->createAuthorization($config, $container);
145150
$this->createRoleHierarchy($config, $container);
@@ -262,8 +267,13 @@ private function createFirewalls(array $config, ContainerBuilder $container)
262267
$authenticationProviders = array_map(function ($id) {
263268
return new Reference($id);
264269
}, array_values(array_unique($authenticationProviders)));
270+
$authenticationManagerId = 'security.authentication.manager.provider';
271+
if ($this->guardAuthenticationManagerEnabled) {
272+
$authenticationManagerId = 'security.authentication.manager.guard';
273+
$container->setAlias('security.authentication.manager', new Alias($authenticationManagerId));
274+
}
265275
$container
266-
->getDefinition('security.authentication.manager')
276+
->getDefinition($authenticationManagerId)
267277
->replaceArgument(0, new IteratorArgument($authenticationProviders))
268278
;
269279

@@ -462,27 +472,20 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri
462472
$key = str_replace('-', '_', $factory->getKey());
463473

464474
if (isset($firewall[$key])) {
465-
if (isset($firewall[$key]['provider'])) {
466-
if (!isset($providerIds[$normalizedName = str_replace('-', '_', $firewall[$key]['provider'])])) {
467-
throw new InvalidConfigurationException(sprintf('Invalid firewall "%s": user provider "%s" not found.', $id, $firewall[$key]['provider']));
475+
$userProvider = $this->getUserProvider($container, $id, $firewall, $key, $defaultProvider, $providerIds);
476+
477+
if ($this->guardAuthenticationManagerEnabled) {
478+
if (!$factory instanceof GuardFactoryInterface) {
479+
throw new InvalidConfigurationException(sprintf('Cannot configure GuardAuthenticationManager as %s authentication does not support it, set security.guard_authentication_manager to `false`.', $key));
468480
}
469-
$userProvider = $providerIds[$normalizedName];
470-
} elseif ('remember_me' === $key) {
471-
// RememberMeFactory will use the firewall secret when created
472-
$userProvider = null;
473-
} elseif ($defaultProvider) {
474-
$userProvider = $defaultProvider;
475-
} elseif (empty($providerIds)) {
476-
$userProvider = sprintf('security.user.provider.missing.%s', $key);
477-
$container->setDefinition($userProvider, (new ChildDefinition('security.user.provider.missing'))->replaceArgument(0, $id));
478-
} else {
479-
throw new InvalidConfigurationException(sprintf('Not configuring explicitly the provider for the "%s" listener on "%s" firewall is ambiguous as there is more than one registered provider.', $key, $id));
480-
}
481481

482-
list($provider, $listenerId, $defaultEntryPoint) = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint);
482+
$authenticationProviders[$id.'_'.$key] = $factory->createGuard($container, $id, $firewall[$key], $userProvider);
483+
} else {
484+
list($provider, $listenerId, $defaultEntryPoint) = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint);
483485

484-
$listeners[] = new Reference($listenerId);
485-
$authenticationProviders[] = $provider;
486+
$listeners[] = new Reference($listenerId);
487+
$authenticationProviders[] = $provider;
488+
}
486489
$hasListeners = true;
487490
}
488491
}
@@ -519,6 +522,40 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri
519522
return [$listeners, $defaultEntryPoint];
520523
}
521524

525+
private function getUserProvider(ContainerBuilder $container, string $id, array $firewall, string $factoryKey, ?string $defaultProvider, array $providerIds): ?string
526+
{
527+
if (isset($firewall[$factoryKey]['provider'])) {
528+
if (!isset($providerIds[$normalizedName = str_replace('-', '_', $firewall[$factoryKey]['provider'])])) {
529+
throw new InvalidConfigurationException(
530+
sprintf('Invalid firewall "%s": user provider "%s" not found.', $id, $firewall[$factoryKey]['provider'])
531+
);
532+
}
533+
534+
return $providerIds[$normalizedName];
535+
}
536+
537+
if ('remember_me' === $factoryKey) {
538+
// RememberMeFactory will use the firewall secret when created
539+
return null;
540+
}
541+
542+
if ($defaultProvider) {
543+
return $defaultProvider;
544+
}
545+
546+
if (empty($providerIds)) {
547+
$userProvider = sprintf('security.user.provider.missing.%s', $factoryKey);
548+
$container->setDefinition(
549+
$userProvider,
550+
(new ChildDefinition('security.user.provider.missing'))->replaceArgument(0, $id)
551+
);
552+
553+
return $userProvider;
554+
}
555+
556+
throw new InvalidConfigurationException(sprintf('Not configuring explicitly the provider for the "%s" listener on "%s" firewall is ambiguous as there is more than one registered provider.', $factoryKey, $id));
557+
}
558+
522559
private function createEncoders(array $encoders, ContainerBuilder $container)
523560
{
524561
$encoderMap = [];
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
5+
6+
<services>
7+
<service id="security.authenticator.basic"
8+
class="Symfony\Component\Security\Core\Authentication\Authenticator\HttpBasicAuthenticator"
9+
abstract="true">
10+
<argument/> <!-- realm name -->
11+
<argument/> <!-- user provider -->
12+
<argument type="service" id="security.encoder_factory" />
13+
<argument type="service" id="logger" on-invalid="null" />
14+
</service>
15+
</services>
16+
</container>

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,22 @@
4040
</service>
4141

4242
<!-- Authentication related services -->
43-
<service id="security.authentication.manager" class="Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager">
43+
<service id="security.authentication.manager.provider" class="Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager">
4444
<argument /> <!-- providers -->
4545
<argument>%security.authentication.manager.erase_credentials%</argument>
4646
<call method="setEventDispatcher">
4747
<argument type="service" id="event_dispatcher" />
4848
</call>
4949
</service>
50+
<service id="security.authentication.manager.guard" class="Symfony\Component\Security\Core\Authentication\GuardAuthenticationManager">
51+
<argument /><!-- guard authenticators -->
52+
<argument /> <!-- User Checker -->
53+
<argument>%security.authentication.manager.erase_credentials%</argument>
54+
<call method="setEventDispatcher">
55+
<argument type="service" id="event_dispatcher" />
56+
</call>
57+
</service>
58+
<service id="security.authentication.manager" alias="security.authentication.manager.provider"/>
5059
<service id="Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface" alias="security.authentication.manager" />
5160

5261
<service id="security.authentication.trust_resolver" class="Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver">

0 commit comments

Comments
 (0)