diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php
index 3afddb3d35..0b99f281e9 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php
@@ -31,7 +31,7 @@ class LoginLinkFactory extends AbstractFactory implements AuthenticatorFactoryIn
public function addConfiguration(NodeDefinition $node)
{
/** @var NodeBuilder $builder */
- $builder = $node->children();
+ $builder = $node->fixXmlConfig('signature_property', 'signature_properties')->children();
$builder
->scalarNode('check_route')
@@ -98,6 +98,10 @@ class LoginLinkFactory extends AbstractFactory implements AuthenticatorFactoryIn
if (null !== $config['max_uses'] && !isset($config['used_link_cache'])) {
$config['used_link_cache'] = 'security.authenticator.cache.expired_links';
+ $defaultCacheDefinition = $container->getDefinition($config['used_link_cache']);
+ if (!$defaultCacheDefinition->hasTag('cache.pool')) {
+ $defaultCacheDefinition->addTag('cache.pool');
+ }
}
$expiredStorageId = null;
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd b/src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd
index 8ff0d5e46d..509ac0b053 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd
@@ -23,6 +23,7 @@
+
@@ -141,6 +142,7 @@
+
@@ -160,6 +162,7 @@
+
@@ -231,6 +234,7 @@
+
@@ -283,6 +287,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_login_link.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_login_link.php
index 2efb089262..2248b5e8ee 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_login_link.php
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_login_link.php
@@ -51,7 +51,6 @@ return static function (ContainerConfigurator $container) {
->set('security.authenticator.cache.expired_links')
->parent('cache.app')
->private()
- ->tag('cache.pool')
->set('security.authenticator.firewall_aware_login_link_handler', FirewallAwareLoginLinkHandler::class)
->args([
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
index 072e33aca6..47d3033a25 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
@@ -21,6 +21,7 @@ use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder;
use Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder;
+use Symfony\Component\Security\Http\Authentication\AuthenticatorManager;
abstract class CompleteConfigurationTest extends TestCase
{
@@ -28,6 +29,38 @@ abstract class CompleteConfigurationTest extends TestCase
abstract protected function getFileExtension();
+ public function testAuthenticatorManager()
+ {
+ $container = $this->getContainer('authenticator_manager');
+
+ $this->assertEquals(AuthenticatorManager::class, $container->getDefinition('security.authenticator.manager.main')->getClass());
+
+ // login link
+ $expiredStorage = $container->getDefinition($expiredStorageId = 'security.authenticator.expired_login_link_storage.main');
+ $this->assertEquals('cache.redis', (string) $expiredStorage->getArgument(0));
+ $this->assertEquals(3600, (string) $expiredStorage->getArgument(1));
+
+ $linker = $container->getDefinition($linkerId = 'security.authenticator.login_link_handler.main');
+ $this->assertEquals(['id', 'email'], $linker->getArgument(3));
+ $this->assertEquals([
+ 'route_name' => 'login_check',
+ 'lifetime' => 3600,
+ 'max_uses' => 1,
+ ], $linker->getArgument(5));
+ $this->assertEquals($expiredStorageId, (string) $linker->getArgument(6));
+
+ $authenticator = $container->getDefinition('security.authenticator.login_link.main');
+ $this->assertEquals($linkerId, (string) $authenticator->getArgument(0));
+ $this->assertEquals([
+ 'check_route' => 'login_check',
+ 'check_post_only' => true,
+ ], $authenticator->getArgument(4));
+
+ // login throttling
+ $listener = $container->getDefinition('security.listener.login_throttling.main');
+ $this->assertEquals('app.rate_limiter', (string) $listener->getArgument(1));
+ }
+
public function testRolesHierarchy()
{
$container = $this->getContainer('container1');
@@ -648,6 +681,7 @@ abstract class CompleteConfigurationTest extends TestCase
$container->setParameter('kernel.debug', false);
$container->setParameter('request_listener.http_port', 80);
$container->setParameter('request_listener.https_port', 443);
+ $container->register('cache.app', \stdClass::class);
$security = new SecurityExtension();
$container->registerExtension($security);
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/authenticator_manager.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/authenticator_manager.php
new file mode 100644
index 0000000000..31a37fe210
--- /dev/null
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/authenticator_manager.php
@@ -0,0 +1,20 @@
+loadFromExtension('security', [
+ 'enable_authenticator_manager' => true,
+ 'firewalls' => [
+ 'main' => [
+ 'login_link' => [
+ 'check_route' => 'login_check',
+ 'check_post_only' => true,
+ 'signature_properties' => ['id', 'email'],
+ 'max_uses' => 1,
+ 'lifetime' => 3600,
+ 'used_link_cache' => 'cache.redis',
+ ],
+ 'login_throttling' => [
+ 'limiter' => 'app.rate_limiter',
+ ],
+ ],
+ ],
+]);
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/authenticator_manager.xml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/authenticator_manager.xml
new file mode 100644
index 0000000000..2a3b643a6e
--- /dev/null
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/authenticator_manager.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ id
+ email
+
+
+
+
+
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/authenticator_manager.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/authenticator_manager.yml
new file mode 100644
index 0000000000..8ff11698ae
--- /dev/null
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/authenticator_manager.yml
@@ -0,0 +1,13 @@
+security:
+ enable_authenticator_manager: true
+ firewalls:
+ main:
+ login_link:
+ check_route: login_check
+ check_post_only: true
+ signature_properties: [id, email]
+ max_uses: 1
+ lifetime: 3600
+ used_link_cache: 'cache.redis'
+ login_throttling:
+ limiter: 'app.rate_limiter'