Skip to content

Commit 0172e56

Browse files
committed
[SecurityBundle] Create a smooth upgrade path for security factories
1 parent b1e2527 commit 0172e56

20 files changed

+299
-93
lines changed

UPGRADE-5.4.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,23 @@ HttpKernel
1111
----------
1212

1313
* Deprecate `AbstractTestSessionListener::getSession` inject a session in the request instead
14+
15+
SecurityBundle
16+
--------------
17+
18+
* Deprecate `SecurityFactoryInterface` and `SecurityExtension::addSecurityListenerFactory()` in favor of
19+
`AuthenticatorFactoryInterface` and `SecurityExtension::addAuthenticatorFactory()`
20+
21+
* Add `AuthenticatorFactoryInterface::getPriority()` which replaces `SecurityFactoryInterface::getPosition()`.
22+
Previous positions are mapped to the following priorities:
23+
24+
| Position | Constant | Priority |
25+
| ----------- | ----------------------------------------------------- | -------- |
26+
| pre_auth | `RemoteUserFactory::PRIORITY`/`X509Factory::PRIORITY` | -10 |
27+
| form | `FormLoginFactory::PRIORITY` | -30 |
28+
| http | `HttpBasicFactory::PRIORITY` | -50 |
29+
| remember_me | `RememberMeFactory::PRIORITY` | -60 |
30+
| anonymous | n/a | -70 |
31+
32+
* Deprecate passing an array of arrays as 1st argument to `MainConfiguration`, pass a sorted flat array of
33+
factories instead.

UPGRADE-6.0.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,21 @@ Security
313313
SecurityBundle
314314
--------------
315315

316+
* Remove `SecurityFactoryInterface` and `SecurityExtension::addSecurityListenerFactory()` in favor of
317+
`AuthenticatorFactoryInterface` and `SecurityExtension::addAuthenticatorFactory()`
318+
* Add `AuthenticatorFactoryInterface::getPriority()` which replaces `SecurityFactoryInterface::getPosition()`.
319+
Previous positions are mapped to the following priorities:
320+
321+
| Position | Constant | Priority |
322+
| ----------- | ----------------------------------------------------- | -------- |
323+
| pre_auth | `RemoteUserFactory::PRIORITY`/`X509Factory::PRIORITY` | -10 |
324+
| form | `FormLoginFactory::PRIORITY` | -30 |
325+
| http | `HttpBasicFactory::PRIORITY` | -50 |
326+
| remember_me | `RememberMeFactory::PRIORITY` | -60 |
327+
| anonymous | n/a | -70 |
328+
329+
* Remove passing an array of arrays as 1st argument to `MainConfiguration`, pass a sorted flat array of
330+
factories instead.
316331
* Remove the `UserPasswordEncoderCommand` class and the corresponding `user:encode-password` command,
317332
use `UserPasswordHashCommand` and `user:hash-password` instead
318333
* Remove the `security.encoder_factory.generic` service, the `security.encoder_factory` and `Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface` aliases,

src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
CHANGELOG
22
=========
33

4+
5.4
5+
---
6+
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.
12+
413
5.3
514
---
615

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
}
@@ -294,19 +305,17 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
294305
;
295306

296307
$abstractFactoryKeys = [];
297-
foreach ($factories as $factoriesAtPosition) {
298-
foreach ($factoriesAtPosition as $factory) {
299-
$name = str_replace('-', '_', $factory->getKey());
300-
$factoryNode = $firewallNodeBuilder->arrayNode($name)
301-
->canBeUnset()
302-
;
303-
304-
if ($factory instanceof AbstractFactory) {
305-
$abstractFactoryKeys[] = $name;
306-
}
307-
308-
$factory->addConfiguration($factoryNode);
308+
foreach ($factories as $factory) {
309+
$name = str_replace('-', '_', $factory->getKey());
310+
$factoryNode = $firewallNodeBuilder->arrayNode($name)
311+
->canBeUnset()
312+
;
313+
314+
if ($factory instanceof AbstractFactory) {
315+
$abstractFactoryKeys[] = $name;
309316
}
317+
318+
$factory->addConfiguration($factoryNode);
310319
}
311320

312321
// 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)