name: SecurityExtension class_comment: '# * SecurityExtension. # * # * @author Fabien Potencier # * @author Johannes M. Schmitt ' dependencies: - name: LogoutUrlExtension type: class source: Symfony\Bridge\Twig\Extension\LogoutUrlExtension - name: AuthenticatorFactoryInterface type: class source: Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AuthenticatorFactoryInterface - name: FirewallListenerFactoryInterface type: class source: Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FirewallListenerFactoryInterface - name: StatelessAuthenticatorFactoryInterface type: class source: Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\StatelessAuthenticatorFactoryInterface - name: UserProviderFactoryInterface type: class source: Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface - name: ConfigurationInterface type: class source: Symfony\Component\Config\Definition\ConfigurationInterface - name: InvalidConfigurationException type: class source: Symfony\Component\Config\Definition\Exception\InvalidConfigurationException - name: FileLocator type: class source: Symfony\Component\Config\FileLocator - name: Application type: class source: Symfony\Component\Console\Application - name: Alias type: class source: Symfony\Component\DependencyInjection\Alias - name: IteratorArgument type: class source: Symfony\Component\DependencyInjection\Argument\IteratorArgument - name: ServiceClosureArgument type: class source: Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument - name: TaggedIteratorArgument type: class source: Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument - name: ChildDefinition type: class source: Symfony\Component\DependencyInjection\ChildDefinition - name: ServiceLocatorTagPass type: class source: Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass - name: ContainerBuilder type: class source: Symfony\Component\DependencyInjection\ContainerBuilder - name: Definition type: class source: Symfony\Component\DependencyInjection\Definition - name: PrependExtensionInterface type: class source: Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface - name: PhpFileLoader type: class source: Symfony\Component\DependencyInjection\Loader\PhpFileLoader - name: Reference type: class source: Symfony\Component\DependencyInjection\Reference - name: EventDispatcher type: class source: Symfony\Component\EventDispatcher\EventDispatcher - name: Expression type: class source: Symfony\Component\ExpressionLanguage\Expression - name: ExpressionLanguage type: class source: Symfony\Component\ExpressionLanguage\ExpressionLanguage - name: PasswordHasherExtension type: class source: Symfony\Component\Form\Extension\PasswordHasher\PasswordHasherExtension - name: ChainRequestMatcher type: class source: Symfony\Component\HttpFoundation\ChainRequestMatcher - name: AttributesRequestMatcher type: class source: Symfony\Component\HttpFoundation\RequestMatcher\AttributesRequestMatcher - name: HostRequestMatcher type: class source: Symfony\Component\HttpFoundation\RequestMatcher\HostRequestMatcher - name: IpsRequestMatcher type: class source: Symfony\Component\HttpFoundation\RequestMatcher\IpsRequestMatcher - name: MethodRequestMatcher type: class source: Symfony\Component\HttpFoundation\RequestMatcher\MethodRequestMatcher - name: PathRequestMatcher type: class source: Symfony\Component\HttpFoundation\RequestMatcher\PathRequestMatcher - name: PortRequestMatcher type: class source: Symfony\Component\HttpFoundation\RequestMatcher\PortRequestMatcher - name: Extension type: class source: Symfony\Component\HttpKernel\DependencyInjection\Extension - name: KernelEvents type: class source: Symfony\Component\HttpKernel\KernelEvents - name: NativePasswordHasher type: class source: Symfony\Component\PasswordHasher\Hasher\NativePasswordHasher - name: Pbkdf2PasswordHasher type: class source: Symfony\Component\PasswordHasher\Hasher\Pbkdf2PasswordHasher - name: PlaintextPasswordHasher type: class source: Symfony\Component\PasswordHasher\Hasher\PlaintextPasswordHasher - name: SodiumPasswordHasher type: class source: Symfony\Component\PasswordHasher\Hasher\SodiumPasswordHasher - name: ContainerLoader type: class source: Symfony\Component\Routing\Loader\ContainerLoader - name: AffirmativeStrategy type: class source: Symfony\Component\Security\Core\Authorization\Strategy\AffirmativeStrategy - name: ConsensusStrategy type: class source: Symfony\Component\Security\Core\Authorization\Strategy\ConsensusStrategy - name: PriorityStrategy type: class source: Symfony\Component\Security\Core\Authorization\Strategy\PriorityStrategy - name: UnanimousStrategy type: class source: Symfony\Component\Security\Core\Authorization\Strategy\UnanimousStrategy - name: VoterInterface type: class source: Symfony\Component\Security\Core\Authorization\Voter\VoterInterface - name: ChainUserChecker type: class source: Symfony\Component\Security\Core\User\ChainUserChecker - name: ChainUserProvider type: class source: Symfony\Component\Security\Core\User\ChainUserProvider - name: UserCheckerInterface type: class source: Symfony\Component\Security\Core\User\UserCheckerInterface - name: UserProviderInterface type: class source: Symfony\Component\Security\Core\User\UserProviderInterface - name: TraceableAuthenticator type: class source: Symfony\Component\Security\Http\Authenticator\Debug\TraceableAuthenticator - name: TraceableAuthenticatorManagerListener type: class source: Symfony\Component\Security\Http\Authenticator\Debug\TraceableAuthenticatorManagerListener - name: CheckPassportEvent type: class source: Symfony\Component\Security\Http\Event\CheckPassportEvent - name: InstallRecipesCommand type: class source: Symfony\Flex\Command\InstallRecipesCommand properties: [] methods: - name: createHasher visibility: private parameters: - name: config comment: "# * SecurityExtension.\n# *\n# * @author Fabien Potencier \n\ # * @author Johannes M. Schmitt \n# */\n# class SecurityExtension\ \ extends Extension implements PrependExtensionInterface\n# {\n# private array\ \ $requestMatchers = [];\n# private array $expressions = [];\n# private array\ \ $contextListeners = [];\n# /** @var list\ \ */\n# private array $factories = [];\n# /** @var AuthenticatorFactoryInterface[]\ \ */\n# private array $sortedFactories = [];\n# private array $userProviderFactories\ \ = [];\n# \n# public function prepend(ContainerBuilder $container): void\n# {\n\ # foreach ($this->getSortedFactories() as $factory) {\n# if ($factory instanceof\ \ PrependExtensionInterface) {\n# $factory->prepend($container);\n# }\n# }\n#\ \ }\n# \n# public function load(array $configs, ContainerBuilder $container):\ \ void\n# {\n# if (!array_filter($configs)) {\n# $hint = class_exists(InstallRecipesCommand::class)\ \ ? 'Try running \"composer symfony:recipes:install symfony/security-bundle\"\ .' : 'Please define your settings for the \"security\" config section.';\n# \n\ # throw new InvalidConfigurationException('The SecurityBundle is enabled but is\ \ not configured. '.$hint);\n# }\n# \n# $mainConfig = $this->getConfiguration($configs,\ \ $container);\n# \n# $config = $this->processConfiguration($mainConfig, $configs);\n\ # \n# // load services\n# $loader = new PhpFileLoader($container, new FileLocator(\\\ dirname(__DIR__).'/Resources/config'));\n# \n# $loader->load('security.php');\n\ # $loader->load('password_hasher.php');\n# $loader->load('security_listeners.php');\n\ # $loader->load('security_authenticator.php');\n# $loader->load('security_authenticator_access_token.php');\n\ # \n# if ($container::willBeAvailable('symfony/twig-bridge', LogoutUrlExtension::class,\ \ ['symfony/security-bundle'])) {\n# $loader->load('templating_twig.php');\n#\ \ }\n# \n# $loader->load('collectors.php');\n# \n# if ($container->hasParameter('kernel.debug')\ \ && $container->getParameter('kernel.debug')) {\n# $loader->load('security_debug.php');\n\ # }\n# \n# if (!$container::willBeAvailable('symfony/expression-language', ExpressionLanguage::class,\ \ ['symfony/security-bundle'])) {\n# $container->removeDefinition('security.expression_language');\n\ # $container->removeDefinition('security.access.expression_voter');\n# $container->removeDefinition('security.is_granted_attribute_expression_language');\n\ # $container->removeDefinition('security.is_csrf_token_valid_attribute_expression_language');\n\ # }\n# \n# if (!class_exists(PasswordHasherExtension::class)) {\n# $container->removeDefinition('form.listener.password_hasher');\n\ # $container->removeDefinition('form.type_extension.form.password_hasher');\n\ # $container->removeDefinition('form.type_extension.password.password_hasher');\n\ # }\n# \n# // set some global scalars\n# $container->setParameter('security.access.denied_url',\ \ $config['access_denied_url']);\n# $container->setParameter('security.authentication.manager.erase_credentials',\ \ $config['erase_credentials']);\n# $container->setParameter('security.authentication.session_strategy.strategy',\ \ $config['session_fixation_strategy']);\n# \n# if (isset($config['access_decision_manager']['service']))\ \ {\n# $container->setAlias('security.access.decision_manager', $config['access_decision_manager']['service']);\n\ # } elseif (isset($config['access_decision_manager']['strategy_service'])) {\n\ # $container\n# ->getDefinition('security.access.decision_manager')\n# ->addArgument(new\ \ Reference($config['access_decision_manager']['strategy_service']));\n# } else\ \ {\n# $container\n# ->getDefinition('security.access.decision_manager')\n# ->addArgument($this->createStrategyDefinition(\n\ # $config['access_decision_manager']['strategy'] ?? MainConfiguration::STRATEGY_AFFIRMATIVE,\n\ # $config['access_decision_manager']['allow_if_all_abstain'],\n# $config['access_decision_manager']['allow_if_equal_granted_denied']\n\ # ));\n# }\n# \n# $container->setParameter('security.authentication.hide_user_not_found',\ \ $config['hide_user_not_found']);\n# \n# if (class_exists(Application::class))\ \ {\n# $loader->load('debug_console.php');\n# }\n# \n# $this->createFirewalls($config,\ \ $container);\n# \n# if ($container::willBeAvailable('symfony/routing', ContainerLoader::class,\ \ ['symfony/security-bundle'])) {\n# $this->createLogoutUrisParameter($config['firewalls']\ \ ?? [], $container);\n# } else {\n# $container->removeDefinition('security.route_loader.logout');\n\ # }\n# \n# $this->createAuthorization($config, $container);\n# $this->createRoleHierarchy($config,\ \ $container);\n# \n# if ($config['password_hashers']) {\n# $this->createHashers($config['password_hashers'],\ \ $container);\n# }\n# \n# if (class_exists(Application::class)) {\n# $loader->load('console.php');\n\ # \n# $container->getDefinition('security.command.user_password_hash')->replaceArgument(1,\ \ array_keys($config['password_hashers']));\n# }\n# \n# $container->registerForAutoconfiguration(VoterInterface::class)\n\ # ->addTag('security.voter');\n# }\n# \n# private function createStrategyDefinition(string\ \ $strategy, bool $allowIfAllAbstainDecisions, bool $allowIfEqualGrantedDeniedDecisions):\ \ Definition\n# {\n# return match ($strategy) {\n# MainConfiguration::STRATEGY_AFFIRMATIVE\ \ => new Definition(AffirmativeStrategy::class, [$allowIfAllAbstainDecisions]),\n\ # MainConfiguration::STRATEGY_CONSENSUS => new Definition(ConsensusStrategy::class,\ \ [$allowIfAllAbstainDecisions, $allowIfEqualGrantedDeniedDecisions]),\n# MainConfiguration::STRATEGY_UNANIMOUS\ \ => new Definition(UnanimousStrategy::class, [$allowIfAllAbstainDecisions]),\n\ # MainConfiguration::STRATEGY_PRIORITY => new Definition(PriorityStrategy::class,\ \ [$allowIfAllAbstainDecisions]),\n# default => throw new InvalidConfigurationException(\\\ sprintf('The strategy \"%s\" is not supported.', $strategy)),\n# };\n# }\n# \n\ # private function createRoleHierarchy(array $config, ContainerBuilder $container):\ \ void\n# {\n# if (!isset($config['role_hierarchy']) || 0 === \\count($config['role_hierarchy']))\ \ {\n# $container->removeDefinition('security.access.role_hierarchy_voter');\n\ # \n# return;\n# }\n# \n# $container->setParameter('security.role_hierarchy.roles',\ \ $config['role_hierarchy']);\n# $container->removeDefinition('security.access.simple_role_voter');\n\ # }\n# \n# private function createAuthorization(array $config, ContainerBuilder\ \ $container): void\n# {\n# foreach ($config['access_control'] as $access) {\n\ # if (isset($access['request_matcher'])) {\n# if ($access['path'] || $access['host']\ \ || $access['port'] || $access['ips'] || $access['methods'] || $access['attributes']\ \ || $access['route']) {\n# throw new InvalidConfigurationException('The \"request_matcher\"\ \ option should not be specified alongside other options. Consider integrating\ \ your constraints inside your RequestMatcher directly.');\n# }\n# $matcher =\ \ new Reference($access['request_matcher']);\n# } else {\n# $attributes = $access['attributes'];\n\ # \n# if ($access['route']) {\n# if (\\array_key_exists('_route', $attributes))\ \ {\n# throw new InvalidConfigurationException('The \"route\" option should not\ \ be specified alongside \"attributes._route\" option. Use just one of the options.');\n\ # }\n# $attributes['_route'] = $access['route'];\n# }\n# \n# $matcher = $this->createRequestMatcher(\n\ # $container,\n# $access['path'],\n# $access['host'],\n# $access['port'],\n# $access['methods'],\n\ # $access['ips'],\n# $attributes\n# );\n# }\n# \n# $roles = $access['roles'];\n\ # if ($access['allow_if']) {\n# $roles[] = $this->createExpression($container,\ \ $access['allow_if']);\n# }\n# \n# $emptyAccess = 0 === \\count(array_filter($access));\n\ # \n# if ($emptyAccess) {\n# throw new InvalidConfigurationException('One or more\ \ access control items are empty. Did you accidentally add lines only containing\ \ a \"-\" under \"security.access_control\"?');\n# }\n# \n# $container->getDefinition('security.access_map')\n\ # ->addMethodCall('add', [$matcher, $roles, $access['requires_channel']]);\n#\ \ }\n# \n# // allow cache warm-up for expressions\n# if (\\count($this->expressions))\ \ {\n# $container->getDefinition('security.cache_warmer.expression')\n# ->replaceArgument(0,\ \ new IteratorArgument(array_values($this->expressions)));\n# } else {\n# $container->removeDefinition('security.cache_warmer.expression');\n\ # }\n# }\n# \n# private function createFirewalls(array $config, ContainerBuilder\ \ $container): void\n# {\n# if (!isset($config['firewalls'])) {\n# return;\n#\ \ }\n# \n# $firewalls = $config['firewalls'];\n# $providerIds = $this->createUserProviders($config,\ \ $container);\n# \n# $container->setParameter('security.firewalls', array_keys($firewalls));\n\ # \n# // make the ContextListener aware of the configured user providers\n# $contextListenerDefinition\ \ = $container->getDefinition('security.context_listener');\n# $arguments = $contextListenerDefinition->getArguments();\n\ # $userProviders = [];\n# foreach ($providerIds as $userProviderId) {\n# $userProviders[]\ \ = new Reference($userProviderId);\n# }\n# $arguments[1] = $userProviderIteratorsArgument\ \ = new IteratorArgument($userProviders);\n# $contextListenerDefinition->setArguments($arguments);\n\ # $nbUserProviders = \\count($userProviders);\n# \n# if ($nbUserProviders > 1)\ \ {\n# $container->setDefinition('security.user_providers', new Definition(ChainUserProvider::class,\ \ [$userProviderIteratorsArgument]));\n# } elseif (0 === $nbUserProviders) {\n\ # $container->removeDefinition('security.listener.user_provider');\n# } else {\n\ # $container->setAlias('security.user_providers', new Alias(current($providerIds)));\n\ # }\n# \n# if (1 === \\count($providerIds)) {\n# $container->setAlias(UserProviderInterface::class,\ \ current($providerIds));\n# }\n# \n# $customUserChecker = false;\n# \n# // load\ \ firewall map\n# $mapDef = $container->getDefinition('security.firewall.map');\n\ # $map = $authenticationProviders = $contextRefs = $authenticators = [];\n# foreach\ \ ($firewalls as $name => $firewall) {\n# if (isset($firewall['user_checker'])\ \ && 'security.user_checker' !== $firewall['user_checker']) {\n# $customUserChecker\ \ = true;\n# }\n# \n# $configId = 'security.firewall.map.config.'.$name;\n# \n\ # [$matcher, $listeners, $exceptionListener, $logoutListener, $firewallAuthenticators]\ \ = $this->createFirewall($container, $name, $firewall, $authenticationProviders,\ \ $providerIds, $configId);\n# \n# if (!$firewallAuthenticators) {\n# $authenticators[$name]\ \ = null;\n# } else {\n# $firewallAuthenticatorRefs = [];\n# foreach ($firewallAuthenticators\ \ as $authenticatorId) {\n# $firewallAuthenticatorRefs[$authenticatorId] = new\ \ Reference($authenticatorId);\n# }\n# $authenticators[$name] = ServiceLocatorTagPass::register($container,\ \ $firewallAuthenticatorRefs);\n# }\n# $contextId = 'security.firewall.map.context.'.$name;\n\ # $isLazy = !$firewall['stateless'] && (!empty($firewall['anonymous']['lazy'])\ \ || $firewall['lazy']);\n# $context = new ChildDefinition($isLazy ? 'security.firewall.lazy_context'\ \ : 'security.firewall.context');\n# $context = $container->setDefinition($contextId,\ \ $context);\n# $context\n# ->replaceArgument(0, new IteratorArgument($listeners))\n\ # ->replaceArgument(1, $exceptionListener)\n# ->replaceArgument(2, $logoutListener)\n\ # ->replaceArgument(3, new Reference($configId))\n# ;\n# \n# $contextRefs[$contextId]\ \ = new Reference($contextId);\n# $map[$contextId] = $matcher;\n# }\n# $container\n\ # ->getDefinition('security.helper')\n# ->replaceArgument(1, $authenticators)\n\ # ;\n# \n# $container->setAlias('security.firewall.context_locator', (string)\ \ ServiceLocatorTagPass::register($container, $contextRefs));\n# \n# $mapDef->replaceArgument(0,\ \ new Reference('security.firewall.context_locator'));\n# $mapDef->replaceArgument(1,\ \ new IteratorArgument($map));\n# \n# // register an autowire alias for the UserCheckerInterface\ \ if no custom user checker service is configured\n# if (!$customUserChecker)\ \ {\n# $container->setAlias(UserCheckerInterface::class, new Alias('security.user_checker',\ \ false));\n# }\n# }\n# \n# private function createFirewall(ContainerBuilder $container,\ \ string $id, array $firewall, array &$authenticationProviders, array $providerIds,\ \ string $configId): array\n# {\n# $config = $container->setDefinition($configId,\ \ new ChildDefinition('security.firewall.config'));\n# $config->replaceArgument(0,\ \ $id);\n# $config->replaceArgument(1, $firewall['user_checker']);\n# \n# // Matcher\n\ # $matcher = null;\n# if (isset($firewall['request_matcher'])) {\n# $matcher =\ \ new Reference($firewall['request_matcher']);\n# } elseif (isset($firewall['pattern'])\ \ || isset($firewall['host'])) {\n# $pattern = $firewall['pattern'] ?? null;\n\ # $host = $firewall['host'] ?? null;\n# $methods = $firewall['methods'] ?? [];\n\ # $matcher = $this->createRequestMatcher($container, $pattern, $host, null, $methods);\n\ # }\n# \n# $config->replaceArgument(2, $matcher ? (string) $matcher : null);\n\ # $config->replaceArgument(3, $firewall['security']);\n# \n# // Security disabled?\n\ # if (false === $firewall['security']) {\n# return [$matcher, [], null, null,\ \ []];\n# }\n# \n# $config->replaceArgument(4, $firewall['stateless']);\n# \n\ # $firewallEventDispatcherId = 'security.event_dispatcher.'.$id;\n# \n# // Provider\ \ id (must be configured explicitly per firewall/authenticator if more than one\ \ provider is set)\n# $defaultProvider = null;\n# if (isset($firewall['provider']))\ \ {\n# if (!isset($providerIds[$normalizedName = str_replace('-', '_', $firewall['provider'])]))\ \ {\n# throw new InvalidConfigurationException(\\sprintf('Invalid firewall \"\ %s\": user provider \"%s\" not found.', $id, $firewall['provider']));\n# }\n#\ \ $defaultProvider = $providerIds[$normalizedName];\n# \n# $container->setDefinition('security.listener.'.$id.'.user_provider',\ \ new ChildDefinition('security.listener.user_provider.abstract'))\n# ->addTag('kernel.event_listener',\ \ ['dispatcher' => $firewallEventDispatcherId, 'event' => CheckPassportEvent::class,\ \ 'priority' => 2048, 'method' => 'checkPassport'])\n# ->replaceArgument(0, new\ \ Reference($defaultProvider));\n# } elseif (1 === \\count($providerIds)) {\n\ # $defaultProvider = reset($providerIds);\n# }\n# \n# $config->replaceArgument(5,\ \ $defaultProvider);\n# \n# // Register Firewall-specific event dispatcher\n#\ \ $container->register($firewallEventDispatcherId, EventDispatcher::class)\n#\ \ ->addTag('event_dispatcher.dispatcher', ['name' => $firewallEventDispatcherId]);\n\ # \n# $eventDispatcherLocator = $container->getDefinition('security.firewall.event_dispatcher_locator');\n\ # $eventDispatcherLocator\n# ->replaceArgument(0, array_merge($eventDispatcherLocator->getArgument(0),\ \ [\n# $id => new ServiceClosureArgument(new Reference($firewallEventDispatcherId)),\n\ # ]))\n# ;\n# \n# // Register Firewall-specific chained user checker\n# $container->register('security.user_checker.chain.'.$id,\ \ ChainUserChecker::class)\n# ->addArgument(new TaggedIteratorArgument('security.user_checker.'.$id));\n\ # \n# // Register listeners\n# $listeners = [];\n# $listenerKeys = [];\n# \n#\ \ // Channel listener\n# $listeners[] = new Reference('security.channel_listener');\n\ # \n# $contextKey = null;\n# // Context serializer listener\n# if (false === $firewall['stateless'])\ \ {\n# $contextKey = $firewall['context'] ?? $id;\n# $listeners[] = new Reference($this->createContextListener($container,\ \ $contextKey, $firewallEventDispatcherId));\n# $sessionStrategyId = 'security.authentication.session_strategy';\n\ # \n# $container\n# ->setDefinition('security.listener.session.'.$id, new ChildDefinition('security.listener.session'))\n\ # ->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]);\n\ # } else {\n# $sessionStrategyId = 'security.authentication.session_strategy_noop';\n\ # }\n# $container->setAlias(new Alias('security.authentication.session_strategy.'.$id,\ \ false), $sessionStrategyId);\n# \n# $config->replaceArgument(6, $contextKey);\n\ # \n# // Logout listener\n# $logoutListenerId = null;\n# if (isset($firewall['logout']))\ \ {\n# $logoutListenerId = 'security.logout_listener.'.$id;\n# $logoutListener\ \ = $container->setDefinition($logoutListenerId, new ChildDefinition('security.logout_listener'));\n\ # $logoutListener->replaceArgument(2, new Reference($firewallEventDispatcherId));\n\ # $logoutListener->replaceArgument(3, [\n# 'csrf_parameter' => $firewall['logout']['csrf_parameter'],\n\ # 'csrf_token_id' => $firewall['logout']['csrf_token_id'],\n# 'logout_path' =>\ \ $firewall['logout']['path'],\n# ]);\n# \n# $container->setDefinition('security.logout.listener.default.'.$id,\ \ new ChildDefinition('security.logout.listener.default'))\n# ->replaceArgument(1,\ \ $firewall['logout']['target'])\n# ->addTag('kernel.event_subscriber', ['dispatcher'\ \ => $firewallEventDispatcherId]);\n# \n# // add CSRF provider\n# if ($firewall['logout']['enable_csrf'])\ \ {\n# $logoutListener->addArgument(new Reference($firewall['logout']['csrf_token_manager']));\n\ # }\n# \n# // add session logout listener\n# if (true === $firewall['logout']['invalidate_session']\ \ && false === $firewall['stateless']) {\n# $container->setDefinition('security.logout.listener.session.'.$id,\ \ new ChildDefinition('security.logout.listener.session'))\n# ->addTag('kernel.event_subscriber',\ \ ['dispatcher' => $firewallEventDispatcherId]);\n# }\n# \n# // add cookie logout\ \ listener\n# if (\\count($firewall['logout']['delete_cookies']) > 0) {\n# $container->setDefinition('security.logout.listener.cookie_clearing.'.$id,\ \ new ChildDefinition('security.logout.listener.cookie_clearing'))\n# ->addArgument($firewall['logout']['delete_cookies'])\n\ # ->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]);\n\ # }\n# \n# // add clear site data listener\n# if ($firewall['logout']['clear_site_data']\ \ ?? false) {\n# $container->setDefinition('security.logout.listener.clear_site_data.'.$id,\ \ new ChildDefinition('security.logout.listener.clear_site_data'))\n# ->addArgument($firewall['logout']['clear_site_data'])\n\ # ->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]);\n\ # }\n# \n# // register with LogoutUrlGenerator\n# $container\n# ->getDefinition('security.logout_url_generator')\n\ # ->addMethodCall('registerListener', [\n# $id,\n# $firewall['logout']['path'],\n\ # $firewall['logout']['csrf_token_id'],\n# $firewall['logout']['csrf_parameter'],\n\ # isset($firewall['logout']['csrf_token_manager']) ? new Reference($firewall['logout']['csrf_token_manager'])\ \ : null,\n# false === $firewall['stateless'] && isset($firewall['context']) ?\ \ $firewall['context'] : null,\n# ])\n# ;\n# \n# $config->replaceArgument(12,\ \ $firewall['logout']);\n# }\n# \n# // Determine default entry point\n# $configuredEntryPoint\ \ = $firewall['entry_point'] ?? null;\n# \n# // Authentication listeners\n# $firewallAuthenticationProviders\ \ = [];\n# [$authListeners, $defaultEntryPoint] = $this->createAuthenticationListeners($container,\ \ $id, $firewall, $firewallAuthenticationProviders, $defaultProvider, $providerIds,\ \ $configuredEntryPoint);\n# \n# // $configuredEntryPoint is resolved into a service\ \ ID and stored in $defaultEntryPoint\n# $configuredEntryPoint = $defaultEntryPoint;\n\ # \n# // authenticator manager\n# $authenticators = array_map(fn ($id) => new\ \ Reference($id), $firewallAuthenticationProviders);\n# $container\n# ->setDefinition($managerId\ \ = 'security.authenticator.manager.'.$id, new ChildDefinition('security.authenticator.manager'))\n\ # ->replaceArgument(0, $authenticators)\n# ->replaceArgument(2, new Reference($firewallEventDispatcherId))\n\ # ->replaceArgument(3, $id)\n# ->replaceArgument(7, $firewall['required_badges']\ \ ?? [])\n# ->addTag('monolog.logger', ['channel' => 'security'])\n# ;\n# \n#\ \ $managerLocator = $container->getDefinition('security.authenticator.managers_locator');\n\ # $managerLocator->replaceArgument(0, array_merge($managerLocator->getArgument(0),\ \ [$id => new ServiceClosureArgument(new Reference($managerId))]));\n# \n# //\ \ authenticator manager listener\n# $container\n# ->setDefinition('security.firewall.authenticator.'.$id,\ \ new ChildDefinition('security.firewall.authenticator'))\n# ->replaceArgument(0,\ \ new Reference($managerId))\n# ;\n# \n# if ($container->hasDefinition('debug.security.firewall'))\ \ {\n# $container\n# ->register('debug.security.firewall.authenticator.'.$id,\ \ TraceableAuthenticatorManagerListener::class)\n# ->setDecoratedService('security.firewall.authenticator.'.$id)\n\ # ->setArguments([new Reference('debug.security.firewall.authenticator.'.$id.'.inner')])\n\ # ->addTag('kernel.reset', ['method' => 'reset'])\n# ;\n# }\n# \n# // user checker\ \ listener\n# $container\n# ->setDefinition('security.listener.user_checker.'.$id,\ \ new ChildDefinition('security.listener.user_checker'))\n# ->replaceArgument(0,\ \ new Reference('security.user_checker.'.$id))\n# ->addTag('kernel.event_subscriber',\ \ ['dispatcher' => $firewallEventDispatcherId]);\n# \n# $listeners[] = new Reference('security.firewall.authenticator.'.$id);\n\ # \n# // Add authenticators to the debug:firewall command\n# if ($container->hasDefinition('security.command.debug_firewall'))\ \ {\n# $debugCommand = $container->getDefinition('security.command.debug_firewall');\n\ # $debugCommand->replaceArgument(3, array_merge($debugCommand->getArgument(3),\ \ [$id => $authenticators]));\n# }\n# \n# $config->replaceArgument(7, $configuredEntryPoint\ \ ?: $defaultEntryPoint);\n# \n# $listeners = array_merge($listeners, $authListeners);\n\ # \n# // Switch user listener\n# if (isset($firewall['switch_user'])) {\n# $listenerKeys[]\ \ = 'switch_user';\n# $listeners[] = new Reference($this->createSwitchUserListener($container,\ \ $id, $firewall['switch_user'], $defaultProvider, $firewall['stateless']));\n\ # }\n# \n# // Access listener\n# $listeners[] = new Reference('security.access_listener');\n\ # \n# // Exception listener\n# $exceptionListener = new Reference($this->createExceptionListener($container,\ \ $firewall, $id, $configuredEntryPoint ?: $defaultEntryPoint, $firewall['stateless']));\n\ # \n# $config->replaceArgument(8, $firewall['access_denied_handler'] ?? null);\n\ # $config->replaceArgument(9, $firewall['access_denied_url'] ?? null);\n# \n#\ \ $container->setAlias('security.user_checker.'.$id, new Alias($firewall['user_checker'],\ \ false));\n# \n# $userCheckerLocator = $container->getDefinition('security.user_checker_locator');\n\ # $userCheckerLocator->replaceArgument(0, array_merge($userCheckerLocator->getArgument(0),\ \ [$id => new ServiceClosureArgument(new Reference('security.user_checker.'.$id))]));\n\ # \n# foreach ($this->getSortedFactories() as $factory) {\n# $key = str_replace('-',\ \ '_', $factory->getKey());\n# if ('custom_authenticators' !== $key && \\array_key_exists($key,\ \ $firewall)) {\n# $listenerKeys[] = $key;\n# }\n# }\n# \n# if ($firewall['custom_authenticators']\ \ ?? false) {\n# foreach ($firewall['custom_authenticators'] as $customAuthenticatorId)\ \ {\n# $listenerKeys[] = $customAuthenticatorId;\n# }\n# }\n# \n# $config->replaceArgument(10,\ \ $listenerKeys);\n# $config->replaceArgument(11, $firewall['switch_user'] ??\ \ null);\n# \n# return [$matcher, $listeners, $exceptionListener, null !== $logoutListenerId\ \ ? new Reference($logoutListenerId) : null, $firewallAuthenticationProviders];\n\ # }\n# \n# private function createContextListener(ContainerBuilder $container,\ \ string $contextKey, ?string $firewallEventDispatcherId): string\n# {\n# if (isset($this->contextListeners[$contextKey]))\ \ {\n# return $this->contextListeners[$contextKey];\n# }\n# \n# $listenerId =\ \ 'security.context_listener.'.\\count($this->contextListeners);\n# $listener\ \ = $container->setDefinition($listenerId, new ChildDefinition('security.context_listener'));\n\ # $listener->replaceArgument(2, $contextKey);\n# if (null !== $firewallEventDispatcherId)\ \ {\n# $listener->replaceArgument(4, new Reference($firewallEventDispatcherId));\n\ # $listener->addTag('kernel.event_listener', ['event' => KernelEvents::RESPONSE,\ \ 'method' => 'onKernelResponse']);\n# }\n# \n# return $this->contextListeners[$contextKey]\ \ = $listenerId;\n# }\n# \n# private function createAuthenticationListeners(ContainerBuilder\ \ $container, string $id, array $firewall, array &$authenticationProviders, ?string\ \ $defaultProvider, array $providerIds, ?string $defaultEntryPoint): array\n#\ \ {\n# $listeners = [];\n# $entryPoints = [];\n# \n# foreach ($this->getSortedFactories()\ \ as $factory) {\n# $key = str_replace('-', '_', $factory->getKey());\n# \n# if\ \ (isset($firewall[$key])) {\n# $userProvider = $this->getUserProvider($container,\ \ $id, $firewall, $key, $defaultProvider, $providerIds);\n# \n# if (!$factory\ \ instanceof AuthenticatorFactoryInterface) {\n# throw new InvalidConfigurationException(\\\ sprintf('Authenticator factory \"%s\" (\"%s\") must implement \"%s\".', get_debug_type($factory),\ \ $key, AuthenticatorFactoryInterface::class));\n# }\n# \n# if (null === $userProvider\ \ && !$factory instanceof StatelessAuthenticatorFactoryInterface) {\n# $userProvider\ \ = $this->createMissingUserProvider($container, $id, $key);\n# }\n# \n# $authenticators\ \ = $factory->createAuthenticator($container, $id, $firewall[$key], $userProvider);\n\ # if (\\is_array($authenticators)) {\n# foreach ($authenticators as $authenticator)\ \ {\n# $authenticationProviders[] = $authenticator;\n# $entryPoints[] = $authenticator;\n\ # }\n# } else {\n# $authenticationProviders[] = $authenticators;\n# $entryPoints[$key]\ \ = $authenticators;\n# }\n# \n# if ($factory instanceof FirewallListenerFactoryInterface)\ \ {\n# $firewallListenerIds = $factory->createListeners($container, $id, $firewall[$key]);\n\ # foreach ($firewallListenerIds as $firewallListenerId) {\n# $listeners[] = new\ \ Reference($firewallListenerId);\n# }\n# }\n# }\n# }\n# \n# if ($container->hasDefinition('debug.security.firewall'))\ \ {\n# foreach ($authenticationProviders as $authenticatorId) {\n# $container->register('debug.'.$authenticatorId,\ \ TraceableAuthenticator::class)\n# ->setDecoratedService($authenticatorId)\n\ # ->setArguments([new Reference('debug.'.$authenticatorId.'.inner')])\n# ;\n#\ \ }\n# }\n# \n# // the actual entry point is configured by the RegisterEntryPointPass\n\ # $container->setParameter('security.'.$id.'._indexed_authenticators', $entryPoints);\n\ # \n# return [$listeners, $defaultEntryPoint];\n# }\n# \n# private function getUserProvider(ContainerBuilder\ \ $container, string $id, array $firewall, string $factoryKey, ?string $defaultProvider,\ \ array $providerIds): ?string\n# {\n# if (isset($firewall[$factoryKey]['provider']))\ \ {\n# if (!isset($providerIds[$normalizedName = str_replace('-', '_', $firewall[$factoryKey]['provider'])]))\ \ {\n# throw new InvalidConfigurationException(\\sprintf('Invalid firewall \"\ %s\": user provider \"%s\" not found.', $id, $firewall[$factoryKey]['provider']));\n\ # }\n# \n# return $providerIds[$normalizedName];\n# }\n# \n# if ($defaultProvider)\ \ {\n# return $defaultProvider;\n# }\n# \n# if (!$providerIds) {\n# if ($firewall['stateless']\ \ ?? false) {\n# return null;\n# }\n# \n# return $this->createMissingUserProvider($container,\ \ $id, $factoryKey);\n# }\n# \n# if ('remember_me' === $factoryKey || 'anonymous'\ \ === $factoryKey) {\n# return 'security.user_providers';\n# }\n# \n# throw new\ \ InvalidConfigurationException(\\sprintf('Not configuring explicitly the provider\ \ for the \"%s\" authenticator on \"%s\" firewall is ambiguous as there is more\ \ than one registered provider. Set the \"provider\" key to one of the configured\ \ providers, even if your custom authenticators don\\'t use it.', $factoryKey,\ \ $id));\n# }\n# \n# private function createMissingUserProvider(ContainerBuilder\ \ $container, string $id, string $factoryKey): string\n# {\n# $userProvider =\ \ \\sprintf('security.user.provider.missing.%s', $factoryKey);\n# $container->setDefinition(\n\ # $userProvider,\n# (new ChildDefinition('security.user.provider.missing'))->replaceArgument(0,\ \ $id)\n# );\n# \n# return $userProvider;\n# }\n# \n# private function createHashers(array\ \ $hashers, ContainerBuilder $container): void\n# {\n# $hasherMap = [];\n# foreach\ \ ($hashers as $class => $hasher) {\n# $hasherMap[$class] = $this->createHasher($hasher);\n\ # }\n# \n# $container\n# ->getDefinition('security.password_hasher_factory')\n\ # ->setArguments([$hasherMap])\n# ;\n# }\n# \n# /**\n# * @param array $config\n# *\n# * @return Reference|array" - name: createUserProviders visibility: private parameters: - name: config - name: container comment: null - name: createUserDaoProvider visibility: private parameters: - name: name - name: provider - name: container comment: null - name: getUserProviderId visibility: private parameters: - name: name comment: null - name: createExceptionListener visibility: private parameters: - name: container - name: config - name: id - name: defaultEntryPoint - name: stateless comment: null - name: createSwitchUserListener visibility: private parameters: - name: container - name: id - name: config - name: defaultProvider - name: stateless comment: null - name: createExpression visibility: private parameters: - name: container - name: expression comment: null - name: createRequestMatcher visibility: private parameters: - name: container - name: path default: 'null' - name: host default: 'null' - name: port default: 'null' - name: methods default: '[]' - name: ips default: 'null' - name: attributes default: '[]' comment: null - name: addAuthenticatorFactory visibility: public parameters: - name: factory comment: null - name: addUserProviderFactory visibility: public parameters: - name: factory comment: null - name: getXsdValidationBasePath visibility: public parameters: [] comment: null - name: getNamespace visibility: public parameters: [] comment: null - name: getConfiguration visibility: public parameters: - name: config - name: container comment: null - name: isValidIps visibility: private parameters: - name: ips comment: null - name: isValidIp visibility: private parameters: - name: cidr comment: null - name: getSortedFactories visibility: private parameters: [] comment: '# * @return array' - name: createLogoutUrisParameter visibility: private parameters: - name: firewallsConfig - name: container comment: null traits: - Symfony\Bridge\Twig\Extension\LogoutUrlExtension - Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AuthenticatorFactoryInterface - Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FirewallListenerFactoryInterface - Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\StatelessAuthenticatorFactoryInterface - Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface - Symfony\Component\Config\Definition\ConfigurationInterface - Symfony\Component\Config\Definition\Exception\InvalidConfigurationException - Symfony\Component\Config\FileLocator - Symfony\Component\Console\Application - Symfony\Component\DependencyInjection\Alias - Symfony\Component\DependencyInjection\Argument\IteratorArgument - Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument - Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument - Symfony\Component\DependencyInjection\ChildDefinition - Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass - Symfony\Component\DependencyInjection\ContainerBuilder - Symfony\Component\DependencyInjection\Definition - Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface - Symfony\Component\DependencyInjection\Loader\PhpFileLoader - Symfony\Component\DependencyInjection\Reference - Symfony\Component\EventDispatcher\EventDispatcher - Symfony\Component\ExpressionLanguage\Expression - Symfony\Component\ExpressionLanguage\ExpressionLanguage - Symfony\Component\Form\Extension\PasswordHasher\PasswordHasherExtension - Symfony\Component\HttpFoundation\ChainRequestMatcher - Symfony\Component\HttpFoundation\RequestMatcher\AttributesRequestMatcher - Symfony\Component\HttpFoundation\RequestMatcher\HostRequestMatcher - Symfony\Component\HttpFoundation\RequestMatcher\IpsRequestMatcher - Symfony\Component\HttpFoundation\RequestMatcher\MethodRequestMatcher - Symfony\Component\HttpFoundation\RequestMatcher\PathRequestMatcher - Symfony\Component\HttpFoundation\RequestMatcher\PortRequestMatcher - Symfony\Component\HttpKernel\DependencyInjection\Extension - Symfony\Component\HttpKernel\KernelEvents - Symfony\Component\PasswordHasher\Hasher\NativePasswordHasher - Symfony\Component\PasswordHasher\Hasher\Pbkdf2PasswordHasher - Symfony\Component\PasswordHasher\Hasher\PlaintextPasswordHasher - Symfony\Component\PasswordHasher\Hasher\SodiumPasswordHasher - Symfony\Component\Routing\Loader\ContainerLoader - Symfony\Component\Security\Core\Authorization\Strategy\AffirmativeStrategy - Symfony\Component\Security\Core\Authorization\Strategy\ConsensusStrategy - Symfony\Component\Security\Core\Authorization\Strategy\PriorityStrategy - Symfony\Component\Security\Core\Authorization\Strategy\UnanimousStrategy - Symfony\Component\Security\Core\Authorization\Voter\VoterInterface - Symfony\Component\Security\Core\User\ChainUserChecker - Symfony\Component\Security\Core\User\ChainUserProvider - Symfony\Component\Security\Core\User\UserCheckerInterface - Symfony\Component\Security\Core\User\UserProviderInterface - Symfony\Component\Security\Http\Authenticator\Debug\TraceableAuthenticator - Symfony\Component\Security\Http\Authenticator\Debug\TraceableAuthenticatorManagerListener - Symfony\Component\Security\Http\Event\CheckPassportEvent - Symfony\Flex\Command\InstallRecipesCommand interfaces: - PrependExtensionInterface