1111
1212namespace Symfony \Bundle \SecurityBundle \DependencyInjection ;
1313
14+ use Symfony \Bundle \SecurityBundle \DependencyInjection \Security \Factory \GuardFactoryInterface ;
1415use Symfony \Bundle \SecurityBundle \DependencyInjection \Security \Factory \RememberMeFactory ;
1516use Symfony \Bundle \SecurityBundle \DependencyInjection \Security \Factory \SecurityFactoryInterface ;
1617use Symfony \Bundle \SecurityBundle \DependencyInjection \Security \UserProvider \UserProviderFactoryInterface ;
@@ -52,6 +53,8 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
5253 private $ userProviderFactories = [];
5354 private $ statelessFirewallKeys = [];
5455
56+ private $ guardAuthenticationManagerEnabled = false ;
57+
5558 public function __construct ()
5659 {
5760 foreach ($ this ->listenerPositions as $ position ) {
@@ -135,6 +138,8 @@ public function load(array $configs, ContainerBuilder $container)
135138 $ container ->setParameter ('security.access.always_authenticate_before_granting ' , $ config ['always_authenticate_before_granting ' ]);
136139 $ container ->setParameter ('security.authentication.hide_user_not_found ' , $ config ['hide_user_not_found ' ]);
137140
141+ $ this ->guardAuthenticationManagerEnabled = $ config ['guard_authentication_manager ' ];
142+
138143 $ this ->createFirewalls ($ config , $ container );
139144 $ this ->createAuthorization ($ config , $ container );
140145 $ this ->createRoleHierarchy ($ config , $ container );
@@ -258,8 +263,13 @@ private function createFirewalls(array $config, ContainerBuilder $container)
258263 $ authenticationProviders = array_map (function ($ id ) {
259264 return new Reference ($ id );
260265 }, 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+ }
261271 $ container
262- ->getDefinition (' security.authentication.manager ' )
272+ ->getDefinition ($ authenticationManagerId )
263273 ->replaceArgument (0 , new IteratorArgument ($ authenticationProviders ))
264274 ;
265275
@@ -467,31 +477,27 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri
467477 $ key = str_replace ('- ' , '_ ' , $ factory ->getKey ());
468478
469479 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 ));
473485 }
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 ;
478486
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 ] = $
E750
authenticator ;
491+ }
492+ } else {
493+ $ authenticationProviders [$ id .'_ ' .$ key ] = $ authenticators ;
481494 }
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 ));
487495 } 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 );
492497
493- $ listeners [] = new Reference ($ listenerId );
494- $ authenticationProviders [] = $ provider ;
498+ $ listeners [] = new Reference ($ listenerId );
499+ $ authenticationProviders [] = $ provider ;
500+ }
495501 $ hasListeners = true ;
496502 }
497503 }
@@ -504,6 +510,42 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri
504510 return [$ listeners , $ defaultEntryPoint ];
505511 }
506512
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+ // RememberM
E750
eFactory 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+
507549 private function createEncoders (array $ encoders , ContainerBuilder $ container )
508550 {
509551 $ encoderMap = [];
0 commit comments