11
11
12
12
namespace Symfony \Bundle \SecurityBundle \DependencyInjection ;
13
13
14
+ use Symfony \Bundle \SecurityBundle \DependencyInjection \Security \Factory \GuardFactoryInterface ;
14
15
use Symfony \Bundle \SecurityBundle \DependencyInjection \Security \Factory \RememberMeFactory ;
15
16
use Symfony \Bundle \SecurityBundle \DependencyInjection \Security \Factory \SecurityFactoryInterface ;
16
17
use Symfony \Bundle \SecurityBundle \DependencyInjection \Security \UserProvider \UserProviderFactoryInterface ;
@@ -52,6 +53,8 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
52
53
private $ userProviderFactories = [];
53
54
private $ statelessFirewallKeys = [];
54
55
56
+ private $ guardAuthenticationManagerEnabled = false ;
57
+
55
58
public function __construct ()
56
59
{
57
60
foreach ($ this ->listenerPositions as $ position ) {
@@ -135,6 +138,8 @@ public function load(array $configs, ContainerBuilder $container)
135
138
$ container ->setParameter ('security.access.always_authenticate_before_granting ' , $ config ['always_authenticate_before_granting ' ]);
136
139
$ container ->setParameter ('security.authentication.hide_user_not_found ' , $ config ['hide_user_not_found ' ]);
137
140
141
+ $ this ->guardAuthenticationManagerEnabled = $ config ['guard_authentication_manager ' ];
142
+
138
143
$ this ->createFirewalls ($ config , $ container );
139
144
$ this ->createAuthorization ($ config , $ container );
140
145
$ this ->createRoleHierarchy ($ config , $ container );
@@ -258,8 +263,13 @@ private function createFirewalls(array $config, ContainerBuilder $container)
258
263
$ authenticationProviders = array_map (function ($ id ) {
259
264
return new Reference ($ id );
260
265
}, array_values (array_unique ($ authenticationProviders )));
266
+ $ authenticationManagerId = 'security.authentication.manager.provider ' ;
267
+ if ($ this ->guardAuthenticationManagerEnabled ) {
268
+ $ authenticationManagerId = 'security.authentication.manager.guard ' ;
269
+ $ container ->setAlias ('security.authentication.manager ' , new Alias ($ authenticationManagerId ));
270
+ }
261
271
$ container
262
- ->getDefinition (' security.authentication.manager ' )
272
+ ->getDefinition ($ authenticationManagerId )
263
273
->replaceArgument (0 , new IteratorArgument ($ authenticationProviders ))
264
274
;
265
275
@@ -467,31 +477,27 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri
467
477
$ key = str_replace ('- ' , '_ ' , $ factory ->getKey ());
468
478
469
479
if (isset ($ firewall [$ key ])) {
470
- if (isset ($ firewall [$ key ]['provider ' ])) {
471
- if (!isset ($ providerIds [$ normalizedName = str_replace ('- ' , '_ ' , $ firewall [$ key ]['provider ' ])])) {
472
- throw new InvalidConfigurationException (sprintf ('Invalid firewall "%s": user provider "%s" not found. ' , $ id , $ firewall [$ key ]['provider ' ]));
480
+ $ userProvider = $ this ->getUserProvider ($ container , $ id , $ firewall , $ key , $ defaultProvider , $ providerIds , $ contextListenerId );
481
+
482
+ if ($ this ->guardAuthenticationManagerEnabled ) {
483
+ if (!$ factory instanceof GuardFactoryInterface) {
484
+ throw new InvalidConfigurationException (sprintf ('Cannot configure GuardAuthenticationManager as %s authentication does not support it, set security.guard_authentication_manager to `false`. ' , $ key ));
473
485
}
474
- $ userProvider = $ providerIds [$ normalizedName ];
475
- } elseif ('remember_me ' === $ key || 'anonymous ' === $ key ) {
476
- // RememberMeFactory will use the firewall secret when created, AnonymousAuthenticationListener does not load users.
477
- $ userProvider = null ;
478
486
479
- if ('remember_me ' === $ key && $ contextListenerId ) {
480
- $ container ->getDefinition ($ contextListenerId )->addTag ('security.remember_me_aware ' , ['id ' => $ id , 'provider ' => 'none ' ]);
487
+ $ authenticators = $ factory ->createGuard ($ container , $ id , $ firewall [$ key ], $ userProvider );
488
+ if (\is_array ($ authenticators )) {
489
+ foreach ($ authenticators as $ i => $ authenticator ) {
490
+ $ authenticationProviders [$ id .'_ ' .$ key .$ i ] = $ authenticator ;
491
+ }
492
+ } else {
493
+ $ authenticationProviders [$ id .'_ ' .$ key ] = $ authenticators ;
481
494
}
482
- } elseif ($ defaultProvider ) {
483
- $ userProvider = $ defaultProvider ;
484
- } elseif (empty ($ providerIds )) {
485
- $ userProvider = sprintf ('security.user.provider.missing.%s ' , $ key );
486
- $ container ->setDefinition ($ userProvider , (new ChildDefinition ('security.user.provider.missing ' ))->replaceArgument (0 , $ id ));
487
495
} else {
488
- 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 ));
489
- }
490
-
491
- list ($ provider , $ listenerId , $ defaultEntryPoint ) = $ factory ->create ($ container , $ id , $ firewall [$ key ], $ userProvider , $ defaultEntryPoint );
496
+ list ($ provider , $ listenerId , $ defaultEntryPoint ) = $ factory ->create ($ container , $ id , $ firewall [$ key ], $ userProvider , $ defaultEntryPoint );
492
497
493
- $ listeners [] = new Reference ($ listenerId );
494
- $ authenticationProviders [] = $ provider ;
498
+ $ listeners [] = new Reference ($ listenerId );
499
+ $ authenticationProviders [] = $ provider ;
500
+ }
495
501
$ hasListeners = true ;
496
502
}
497
503
}
@@ -504,6 +510,42 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri
504
510
return [$ listeners , $ defaultEntryPoint ];
505
511
}
506
512
513
+ private function getUserProvider (ContainerBuilder $ container , string $ id , array $ firewall , string $ factoryKey , ?string $ defaultProvider , array $ providerIds , ?string $ contextListenerId ): ?string
514
+ {
515
+ if (isset ($ firewall [$ factoryKey ]['provider ' ])) {
516
+ if (!isset ($ providerIds [$ normalizedName = str_replace ('- ' , '_ ' , $ firewall [$ factoryKey ]['provider ' ])])) {
517
+ throw new InvalidConfigurationException (sprintf ('Invalid firewall "%s": user provider "%s" not found. ' , $ id , $ firewall [$ factoryKey ]['provider ' ]));
518
+ }
519
+
520
+ return $ providerIds [$ normalizedName ];
521
+ }
522
+
523
+ if ('remember_me ' === $ factoryKey || 'anonymous ' === $ factoryKey ) {
524
+ if ('remember_me ' === $ factoryKey && $ contextListenerId ) {
525
+ $ container ->getDefinition ($ contextListenerId )->addTag ('security.remember_me_aware ' , ['id ' => $ id , 'provider ' => 'none ' ]);
526
+ }
527
+
528
+ // RememberMeFactory will use the firewall secret when created
529
+ return null ;
530
+ }
531
+
532
+ if ($ defaultProvider ) {
533
+ return $ defaultProvider ;
534
+ }
535
+
536
+ if (!$ providerIds ) {
537
+ $ userProvider = sprintf ('security.user.provider.missing.%s ' , $ factoryKey );
538
+ $ container ->setDefinition (
539
+ $ userProvider ,
540
+ (new ChildDefinition ('security.user.provider.missing ' ))->replaceArgument (0 , $ id )
541
+ );
542
+
543
+ return $ userProvider ;
544
+ }
545
+
546
+ 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 ));
547
+ }
548
+
507
549
private function createEncoders (array $ encoders , ContainerBuilder $ container )
508
550
{
509
551
$ encoderMap = [];
0 commit comments