Skip to content

Commit 8e984fa

Browse files
committed
feature #41754 [SecurityBundle] Create a smooth upgrade path for security factories (wouterj)
This PR was merged into the 5.4 branch. Discussion ---------- [SecurityBundle] Create a smooth upgrade path for security factories | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | no | New feature? | yes | Deprecations? | yes | Tickets | Ref #41613 (comment) | License | MIT | Doc PR | - This change allows removing `SecurityFactoryInterface` in Symfony 6. I've also changed the discrete ordering using "listener positions" to the much more common continuous ordering using priorities. I feel like priorities are much more self-explanatory. Commits ------- 7385fd5 [SecurityBundle] Create a smooth upgrade path for security factories
2 parents 65e1463 + 7385fd5 commit 8e984fa

20 files changed

+290
-93
lines changed

UPGRADE-5.4.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,21 @@ Messenger
3737
SecurityBundle
3838
--------------
3939

40+
* Deprecate `SecurityFactoryInterface` and `SecurityExtension::addSecurityListenerFactory()` in favor of
41+
`AuthenticatorFactoryInterface` and `SecurityExtension::addAuthenticatorFactory()`
42+
* Add `AuthenticatorFactoryInterface::getPriority()` which replaces `SecurityFactoryInterface::getPosition()`.
43+
Previous positions are mapped to the following priorities:
44+
45+
| Position | Constant | Priority |
46+
| ----------- | ----------------------------------------------------- | -------- |
47+
| pre_auth | `RemoteUserFactory::PRIORITY`/`X509Factory::PRIORITY` | -10 |
48+
| form | `FormLoginFactory::PRIORITY` | -30 |
49+
| http | `HttpBasicFactory::PRIORITY` | -50 |
50+
| remember_me | `RememberMeFactory::PRIORITY` | -60 |
51+
| anonymous | n/a | -70 |
52+
53+
* Deprecate passing an array of arrays as 1st argument to `MainConfiguration`, pass a sorted flat array of
54+
factories instead.
4055
* Deprecate the `always_authenticate_before_granting` option
4156

4257
Security

UPGRADE-6.0.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,21 @@ Security
355355
SecurityBundle
356356
--------------
357357

358+
* Remove `SecurityFactoryInterface` and `SecurityExtension::addSecurityListenerFactory()` in favor of
359+
`AuthenticatorFactoryInterface` and `SecurityExtension::addAuthenticatorFactory()`
360+
* Add `AuthenticatorFactoryInterface::getPriority()` which replaces `SecurityFactoryInterface::getPosition()`.
361+
Previous positions are mapped to the following priorities:
362+
363+
| Position | Constant | Priority |
364+
| ----------- | ----------------------------------------------------- | -------- |
365+
| pre_auth | `RemoteUserFactory::PRIORITY`/`X509Factory::PRIORITY` | -10 |
366+
| form | `FormLoginFactory::PRIORITY` | -30 |
367+
| http | `HttpBasicFactory::PRIORITY` | -50 |
368+
| remember_me | `RememberMeFactory::PRIORITY` | -60 |
369+
| anonymous | n/a | -70 |
370+
371+
* Remove passing an array of arrays as 1st argument to `MainConfiguration`, pass a sorted flat array of
372+
factories instead.
358373
* Remove the `always_authenticate_before_granting` option
359374
* Remove the `UserPasswordEncoderCommand` class and the corresponding `user:encode-password` command,
360375
use `UserPasswordHashCommand` and `user:hash-password` instead

src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ CHANGELOG
44
5.4
55
---
66

7+
* Deprecate `SecurityFactoryInterface` and `SecurityExtension::addSecurityListenerFactory()` in favor of
8+
`AuthenticatorFactoryInterface` and `SecurityExtension::addAuthenticatorFactory()`
9+
* Add `AuthenticatorFactoryInterface::getPriority()` which replaces `SecurityFactoryInterface::getPosition()`
10+
* Deprecate passing an array of arrays as 1st argument to `MainConfiguration`, pass a sorted flat array of
11+
factories instead.
712
* Deprecate the `always_authenticate_before_granting` option
813

914
5.3

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

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Bundle\SecurityBundle\DependencyInjection;
1313

1414
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory;
15+
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AuthenticatorFactoryInterface;
16+
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
1517
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
1618
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
1719
use Symfony\Component\Config\Definition\ConfigurationInterface;
@@ -31,8 +33,17 @@ class MainConfiguration implements ConfigurationInterface
3133
private $factories;
3234
private $userProviderFactories;
3335

36+
/**
37+
* @param (SecurityFactoryInterface|AuthenticatorFactoryInterface)[] $factories
38+
*/
3439
public function __construct(array $factories, array $userProviderFactories)
3540
{
41+
if (\is_array(current($factories))) {
42+
trigger_deprecation('symfony/security-bundle', '5.4', 'Passing an array of arrays as 1st argument to "%s" is deprecated, pass a sorted array of factories instead.', __METHOD__);
43+
44+
$factories = array_merge(...array_values($factories));
45+
}
46+
3647
$this->factories = $factories;
3748
$this->userProviderFactories = $userProviderFactories;
3849
}
@@ -297,19 +308,17 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
297308
;
298309

299310
$abstractFactoryKeys = [];
300-
foreach ($factories as $factoriesAtPosition) {
301-
foreach ($factoriesAtPosition as $factory) {
302-
$name = str_replace('-', '_', $factory->getKey());
303-
$factoryNode = $firewallNodeBuilder->arrayNode($name)
304-
->canBeUnset()
305-
;
306-
307-
if ($factory instanceof AbstractFactory) {
308-
$abstractFactoryKeys[] = $name;
309-
}
310-
311-
$factory->addConfiguration($factoryNode);
311+
foreach ($factories as $factory) {
312+
$name = str_replace('-', '_', $factory->getKey());
313+
$factoryNode = $firewallNodeBuilder->arrayNode($name)
314+
->canBeUnset()
315+
;
316+
317+
if ($factory instanceof AbstractFactory) {
318+
$abstractFactoryKeys[] = $name;
312319
}
320+
321+
$factory->addConfiguration($factoryNode);
313322
}
314323

315324
// check for unreachable check paths

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal
5252
throw new InvalidConfigurationException(sprintf('The authenticator manager no longer has "anonymous" security. Please remove this option under the "%s" firewall'.($config['lazy'] ? ' and add "lazy: true"' : '').'.', $firewallName));
5353
}
5454

55+
public function getPriority()
56+
{
57+
return -60;
58+
}
59+
5560
public function getPosition()
5661
{
5762
return 'anonymous';

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111

1212
namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory;
1313

14+
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
1415
use Symfony\Component\DependencyInjection\ContainerBuilder;
1516

1617
/**
18+
* @method int getPriority() defines the position at which the authenticator is called
19+
*
1720
* @author Wouter de Jong <wouter@wouterj.nl>
1821
*/
1922
interface AuthenticatorFactoryInterface
@@ -24,4 +27,14 @@ interface AuthenticatorFactoryInterface
2427
* @return string|string[] The authenticator service ID(s) to be used by the firewall
2528
*/
2629
public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId);
30+
31+
/**
32+
* Defines the configuration key used to reference the authenticator
33+
* in the firewall configuration.
34+
*
35+
* @return string
36+
*/
37+
public function getKey();
38+
39+
public function addConfiguration(NodeDefinition $builder);
2740
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ public function create(ContainerBuilder $container, string $id, array $config, s
2727
throw new \LogicException('Custom authenticators are not supported when "security.enable_authenticator_manager" is not set to true.');
2828
}
2929

30+
public function getPriority(): int
31+
{
32+
return 0;
33+
}
34+
3035
public function getPosition(): string
3136
{
3237
return 'pre_auth';

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
*/
2828
class FormLoginFactory extends AbstractFactory implements AuthenticatorFactoryInterface
2929
{
30+
public const PRIORITY = -30;
31+
3032
public function __construct()
3133
{
3234
$this->addOption('username_parameter', '_username');
@@ -37,6 +39,11 @@ public function __construct()
3739
$this->addOption('post_only', true);
3840
}
3941

42+
public function getPriority(): int
43+
{
44+
return self::PRIORITY;
45+
}
46+
4047
public function getPosition()
4148
{
4249
return 'form';

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ public function getPosition()
3434
return 'pre_auth';
3535
}
3636

37+
public function getPriority(): int
38+
{
39+
return 0;
40+
}
41+
3742
public function getKey()
3843
{
3944
return 'guard';

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
*/
2626
class HttpBasicFactory implements SecurityFactoryInterface, AuthenticatorFactoryInterface
2727
{
28+
public const PRIORITY = -50;
29+
2830
public function create(ContainerBuilder $container, string $id, array $config, string $userProvider, ?string $defaultEntryPoint)
2931
{
3032
$provider = 'security.authentication.provider.dao.'.$id;
@@ -66,6 +68,11 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal
6668
return $authenticatorId;
6769
}
6870

71+
public function getPriority(): int
72+
{
73+
return self::PRIORITY;
74+
}
75+
6976
public function getPosition()
7077
{
7178
return 'http';

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy