bug #40490 [Security] Add XML support for authenticator manager (wouterj)
This PR was squashed before being merged into the 5.2 branch.
Discussion
----------
[Security] Add XML support for authenticator manager
| Q | A
| ------------- | ---
| Branch? | 5.2
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
I discovered we didn't have tests for the experimental configuration and it turns out it didn't support XML at all (this does bring up the question if it's worth maintaining XML support in Symfony).
Commits
-------
77fb0eb0a1
[Security] Add XML support for authenticator manager
This commit is contained in:
commit
827cf0a1a3
@ -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;
|
||||
|
@ -23,6 +23,7 @@
|
||||
<xsd:attribute name="hide-user-not-found" type="xsd:boolean" />
|
||||
<xsd:attribute name="always-authenticate-before-granting" type="xsd:boolean" />
|
||||
<xsd:attribute name="erase-credentials" type="xsd:boolean" />
|
||||
<xsd:attribute name="enable-authenticator-manager" type="xsd:boolean" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="encoders">
|
||||
@ -141,6 +142,7 @@
|
||||
<xsd:element name="http-basic-ldap" type="http_basic_ldap" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="json-login" type="json_login" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="json-login-ldap" type="json_login_ldap" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="login-throttling" type="login_throttling" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="remember-me" type="remember_me" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="remote-user" type="remote_user" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="x509" type="x509" minOccurs="0" maxOccurs="1" />
|
||||
@ -160,6 +162,7 @@
|
||||
<xsd:attribute name="provider" type="xsd:string" />
|
||||
<xsd:attribute name="stateless" type="xsd:boolean" />
|
||||
<xsd:attribute name="context" type="xsd:string" />
|
||||
<xsd:attribute name="lazy" type="xsd:boolean" />
|
||||
<!-- allow factories to use dynamic elements -->
|
||||
<xsd:anyAttribute processContents="lax" />
|
||||
</xsd:complexType>
|
||||
@ -231,6 +234,7 @@
|
||||
<xsd:attribute name="csrf-token-id" type="xsd:string" />
|
||||
<xsd:attribute name="post-only" type="xsd:boolean" />
|
||||
<xsd:attribute name="csrf-token-generator" type="xsd:string" />
|
||||
<xsd:attribute name="enable-csrf" type="xsd:boolean" />
|
||||
<xsd:attributeGroup ref="success-handler-options" />
|
||||
<xsd:attributeGroup ref="failure-handler-options" />
|
||||
</xsd:extension>
|
||||
@ -283,6 +287,25 @@
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="login_link">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="signature-property" type="xsd:string" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="check-route" type="xsd:string" />
|
||||
<xsd:attribute name="check-post-only" type="xsd:boolean" />
|
||||
<xsd:attribute name="lifetime" type="xsd:integer" />
|
||||
<xsd:attribute name="max-uses" type="xsd:integer" />
|
||||
<xsd:attribute name="used-link-cache" type="xsd:string" />
|
||||
<xsd:attribute name="success-handler" type="xsd:string" />
|
||||
<xsd:attribute name="failure-handler" type="xsd:string" />
|
||||
<xsd:attribute name="provider" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="login_throttling">
|
||||
<xsd:attribute name="limiter" type="xsd:string" />
|
||||
<xsd:attribute name="max-attempts" type="xsd:integer" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="remember_me">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="user-provider" type="xsd:string" />
|
||||
|
@ -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([
|
||||
|
@ -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);
|
||||
|
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
$container->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',
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<srv:container xmlns="http://symfony.com/schema/dic/security"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:srv="http://symfony.com/schema/dic/services"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||||
https://symfony.com/schema/dic/services/services-1.0.xsd
|
||||
http://symfony.com/schema/dic/security
|
||||
https://symfony.com/schema/dic/security/security-1.0.xsd">
|
||||
|
||||
<config enable-authenticator-manager="true">
|
||||
<firewall name="main">
|
||||
<login-link check-route="login_check"
|
||||
check-post-only="true"
|
||||
max-uses="1"
|
||||
lifetime="3600"
|
||||
used-link-cache="cache.redis"
|
||||
>
|
||||
<signature-property>id</signature-property>
|
||||
<signature-property>email</signature-property>
|
||||
</login-link>
|
||||
<login-throttling limiter="app.rate_limiter"/>
|
||||
</firewall>
|
||||
</config>
|
||||
</srv:container>
|
@ -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'
|
Reference in New Issue
Block a user