vendor/symfony/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Symfony\Bundle\SecurityBundle\DependencyInjection;
       
    13 
       
    14 use Symfony\Component\DependencyInjection\DefinitionDecorator;
       
    15 use Symfony\Component\DependencyInjection\Alias;
       
    16 use Symfony\Component\HttpKernel\DependencyInjection\Extension;
       
    17 use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
       
    18 use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
       
    19 use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
       
    20 use Symfony\Component\Config\Loader\DelegatingLoader;
       
    21 use Symfony\Component\Config\Loader\LoaderResolver;
       
    22 use Symfony\Component\DependencyInjection\ContainerBuilder;
       
    23 use Symfony\Component\DependencyInjection\Reference;
       
    24 use Symfony\Component\DependencyInjection\Parameter;
       
    25 use Symfony\Component\Config\FileLocator;
       
    26 
       
    27 /**
       
    28  * SecurityExtension.
       
    29  *
       
    30  * @author Fabien Potencier <fabien@symfony.com>
       
    31  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
       
    32  */
       
    33 class SecurityExtension extends Extension
       
    34 {
       
    35     private $requestMatchers = array();
       
    36     private $contextListeners = array();
       
    37     private $listenerPositions = array('pre_auth', 'form', 'http', 'remember_me');
       
    38     private $factories;
       
    39 
       
    40     public function load(array $configs, ContainerBuilder $container)
       
    41     {
       
    42         if (!array_filter($configs)) {
       
    43             return;
       
    44         }
       
    45 
       
    46         // first assemble the factories
       
    47         $factoriesConfig = new FactoryConfiguration();
       
    48         $config = $this->processConfiguration($factoriesConfig, $configs);
       
    49         $factories = $this->createListenerFactories($container, $config);
       
    50 
       
    51         // normalize and merge the actual configuration
       
    52         $mainConfig = new MainConfiguration($factories);
       
    53         $config = $this->processConfiguration($mainConfig, $configs);
       
    54 
       
    55         // load services
       
    56         $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
       
    57         $loader->load('security.xml');
       
    58         $loader->load('security_listeners.xml');
       
    59         $loader->load('security_rememberme.xml');
       
    60         $loader->load('templating_php.xml');
       
    61         $loader->load('templating_twig.xml');
       
    62         $loader->load('collectors.xml');
       
    63 
       
    64         // set some global scalars
       
    65         $container->setParameter('security.access.denied_url', $config['access_denied_url']);
       
    66         $container->setParameter('security.authentication.session_strategy.strategy', $config['session_fixation_strategy']);
       
    67         $container
       
    68             ->getDefinition('security.access.decision_manager')
       
    69             ->addArgument($config['access_decision_manager']['strategy'])
       
    70             ->addArgument($config['access_decision_manager']['allow_if_all_abstain'])
       
    71             ->addArgument($config['access_decision_manager']['allow_if_equal_granted_denied'])
       
    72         ;
       
    73         $container->setParameter('security.access.always_authenticate_before_granting', $config['always_authenticate_before_granting']);
       
    74         $container->setParameter('security.authentication.hide_user_not_found', $config['hide_user_not_found']);
       
    75 
       
    76         $this->createFirewalls($config, $container);
       
    77         $this->createAuthorization($config, $container);
       
    78         $this->createRoleHierarchy($config, $container);
       
    79 
       
    80         if ($config['encoders']) {
       
    81             $this->createEncoders($config['encoders'], $container);
       
    82         }
       
    83 
       
    84         // load ACL
       
    85         if (isset($config['acl'])) {
       
    86             $this->aclLoad($config['acl'], $container);
       
    87         }
       
    88 
       
    89         // add some required classes for compilation
       
    90         $this->addClassesToCompile(array(
       
    91             'Symfony\\Component\\Security\\Http\\Firewall',
       
    92             'Symfony\\Component\\Security\\Http\\FirewallMapInterface',
       
    93             'Symfony\\Component\\Security\\Core\\SecurityContext',
       
    94             'Symfony\\Component\\Security\\Core\\SecurityContextInterface',
       
    95             'Symfony\\Component\\Security\\Core\\User\\UserProviderInterface',
       
    96             'Symfony\\Component\\Security\\Core\\Authentication\\AuthenticationProviderManager',
       
    97             'Symfony\\Component\\Security\\Core\\Authentication\\AuthenticationManagerInterface',
       
    98             'Symfony\\Component\\Security\\Core\\Authorization\\AccessDecisionManager',
       
    99             'Symfony\\Component\\Security\\Core\\Authorization\\AccessDecisionManagerInterface',
       
   100             'Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface',
       
   101 
       
   102             'Symfony\\Bundle\\SecurityBundle\\Security\\FirewallMap',
       
   103             'Symfony\\Bundle\\SecurityBundle\\Security\\FirewallContext',
       
   104 
       
   105             'Symfony\\Component\\HttpFoundation\\RequestMatcher',
       
   106             'Symfony\\Component\\HttpFoundation\\RequestMatcherInterface',
       
   107         ));
       
   108     }
       
   109 
       
   110     private function aclLoad($config, ContainerBuilder $container)
       
   111     {
       
   112         $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
       
   113         $loader->load('security_acl.xml');
       
   114 
       
   115         if (isset($config['cache']['id'])) {
       
   116             $container->setAlias('security.acl.cache', $config['cache']['id']);
       
   117         }
       
   118         $container->getDefinition('security.acl.voter.basic_permissions')->addArgument($config['voter']['allow_if_object_identity_unavailable']);
       
   119 
       
   120         // custom ACL provider
       
   121         if (isset($config['provider'])) {
       
   122             $container->setAlias('security.acl.provider', $config['provider']);
       
   123 
       
   124             return;
       
   125         }
       
   126 
       
   127         $this->configureDbalAclProvider($config, $container, $loader);
       
   128     }
       
   129 
       
   130     private function configureDbalAclProvider(array $config, ContainerBuilder $container, $loader)
       
   131     {
       
   132         $loader->load('security_acl_dbal.xml');
       
   133 
       
   134         if (isset($config['connection'])) {
       
   135             $container->setAlias('security.acl.dbal.connection', sprintf('doctrine.dbal.%s_connection', $config['connection']));
       
   136         }
       
   137         $container->getDefinition('security.acl.cache.doctrine')->addArgument($config['cache']['prefix']);
       
   138 
       
   139         $container->setParameter('security.acl.dbal.class_table_name', $config['tables']['class']);
       
   140         $container->setParameter('security.acl.dbal.entry_table_name', $config['tables']['entry']);
       
   141         $container->setParameter('security.acl.dbal.oid_table_name', $config['tables']['object_identity']);
       
   142         $container->setParameter('security.acl.dbal.oid_ancestors_table_name', $config['tables']['object_identity_ancestors']);
       
   143         $container->setParameter('security.acl.dbal.sid_table_name', $config['tables']['security_identity']);
       
   144     }
       
   145 
       
   146     /**
       
   147      * Loads the web configuration.
       
   148      *
       
   149      * @param array            $config    An array of configuration settings
       
   150      * @param ContainerBuilder $container A ContainerBuilder instance
       
   151      */
       
   152 
       
   153     private function createRoleHierarchy($config, ContainerBuilder $container)
       
   154     {
       
   155         if (!isset($config['role_hierarchy'])) {
       
   156             $container->removeDefinition('security.access.role_hierarchy_voter');
       
   157 
       
   158             return;
       
   159         }
       
   160 
       
   161         $container->setParameter('security.role_hierarchy.roles', $config['role_hierarchy']);
       
   162         $container->removeDefinition('security.access.simple_role_voter');
       
   163     }
       
   164 
       
   165     private function createAuthorization($config, ContainerBuilder $container)
       
   166     {
       
   167         if (!$config['access_control']) {
       
   168             return;
       
   169         }
       
   170 
       
   171         $this->addClassesToCompile(array(
       
   172             'Symfony\\Component\\Security\\Http\\AccessMap',
       
   173         ));
       
   174 
       
   175         foreach ($config['access_control'] as $access) {
       
   176             $matcher = $this->createRequestMatcher(
       
   177                 $container,
       
   178                 $access['path'],
       
   179                 $access['host'],
       
   180                 count($access['methods']) === 0 ? null : $access['methods'],
       
   181                 $access['ip']
       
   182             );
       
   183 
       
   184             $container->getDefinition('security.access_map')
       
   185                       ->addMethodCall('add', array($matcher, $access['roles'], $access['requires_channel']));
       
   186         }
       
   187     }
       
   188 
       
   189     private function createFirewalls($config, ContainerBuilder $container)
       
   190     {
       
   191         if (!isset($config['firewalls'])) {
       
   192             return;
       
   193         }
       
   194 
       
   195         $firewalls = $config['firewalls'];
       
   196         $providerIds = $this->createUserProviders($config, $container);
       
   197 
       
   198         // make the ContextListener aware of the configured user providers
       
   199         $definition = $container->getDefinition('security.context_listener');
       
   200         $arguments = $definition->getArguments();
       
   201         $userProviders = array();
       
   202         foreach ($providerIds as $userProviderId) {
       
   203             $userProviders[] = new Reference($userProviderId);
       
   204         }
       
   205         $arguments[1] = $userProviders;
       
   206         $definition->setArguments($arguments);
       
   207 
       
   208         // create security listener factories
       
   209         $factories = $this->createListenerFactories($container, $config);
       
   210 
       
   211         // load firewall map
       
   212         $mapDef = $container->getDefinition('security.firewall.map');
       
   213         $map = $authenticationProviders = array();
       
   214         foreach ($firewalls as $name => $firewall) {
       
   215             list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $factories);
       
   216 
       
   217             $contextId = 'security.firewall.map.context.'.$name;
       
   218             $context = $container->setDefinition($contextId, new DefinitionDecorator('security.firewall.context'));
       
   219             $context
       
   220                 ->replaceArgument(0, $listeners)
       
   221                 ->replaceArgument(1, $exceptionListener)
       
   222             ;
       
   223             $map[$contextId] = $matcher;
       
   224         }
       
   225         $mapDef->replaceArgument(1, $map);
       
   226 
       
   227         // add authentication providers to authentication manager
       
   228         $authenticationProviders = array_map(function($id) {
       
   229             return new Reference($id);
       
   230         }, array_values(array_unique($authenticationProviders)));
       
   231         $container
       
   232             ->getDefinition('security.authentication.manager')
       
   233             ->replaceArgument(0, $authenticationProviders)
       
   234         ;
       
   235     }
       
   236 
       
   237     private function createFirewall(ContainerBuilder $container, $id, $firewall, &$authenticationProviders, $providerIds, array $factories)
       
   238     {
       
   239         // Matcher
       
   240         $i = 0;
       
   241         $matcher = null;
       
   242         if (isset($firewall['request_matcher'])) {
       
   243             $matcher = new Reference($firewall['request_matcher']);
       
   244         } else if (isset($firewall['pattern'])) {
       
   245             $matcher = $this->createRequestMatcher($container, $firewall['pattern']);
       
   246         }
       
   247 
       
   248         // Security disabled?
       
   249         if (false === $firewall['security']) {
       
   250             return array($matcher, array(), null);
       
   251         }
       
   252 
       
   253         // Provider id (take the first registered provider if none defined)
       
   254         if (isset($firewall['provider'])) {
       
   255             $defaultProvider = $this->getUserProviderId($firewall['provider']);
       
   256         } else {
       
   257             $defaultProvider = reset($providerIds);
       
   258         }
       
   259 
       
   260         // Register listeners
       
   261         $listeners = array();
       
   262 
       
   263         // Channel listener
       
   264         $listeners[] = new Reference('security.channel_listener');
       
   265 
       
   266         // Context serializer listener
       
   267         if (false === $firewall['stateless']) {
       
   268             $contextKey = $id;
       
   269             if (isset($firewall['context'])) {
       
   270                 $contextKey = $firewall['context'];
       
   271             }
       
   272 
       
   273             $listeners[] = new Reference($this->createContextListener($container, $contextKey));
       
   274         }
       
   275 
       
   276         // Logout listener
       
   277         if (isset($firewall['logout'])) {
       
   278             $listenerId = 'security.logout_listener.'.$id;
       
   279             $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.logout_listener'));
       
   280             $listener->replaceArgument(2, $firewall['logout']['path']);
       
   281             $listener->replaceArgument(3, $firewall['logout']['target']);
       
   282             $listeners[] = new Reference($listenerId);
       
   283 
       
   284             // add logout success handler
       
   285             if (isset($firewall['logout']['success_handler'])) {
       
   286                 $listener->replaceArgument(4, new Reference($firewall['logout']['success_handler']));
       
   287             }
       
   288 
       
   289             // add session logout handler
       
   290             if (true === $firewall['logout']['invalidate_session'] && false === $firewall['stateless']) {
       
   291                 $listener->addMethodCall('addHandler', array(new Reference('security.logout.handler.session')));
       
   292             }
       
   293 
       
   294             // add cookie logout handler
       
   295             if (count($firewall['logout']['delete_cookies']) > 0) {
       
   296                 $cookieHandlerId = 'security.logout.handler.cookie_clearing.'.$id;
       
   297                 $cookieHandler = $container->setDefinition($cookieHandlerId, new DefinitionDecorator('security.logout.handler.cookie_clearing'));
       
   298                 $cookieHandler->addArgument($firewall['logout']['delete_cookies']);
       
   299 
       
   300                 $listener->addMethodCall('addHandler', array(new Reference($cookieHandlerId)));
       
   301             }
       
   302 
       
   303             // add custom handlers
       
   304             foreach ($firewall['logout']['handlers'] as $handlerId) {
       
   305                 $listener->addMethodCall('addHandler', array(new Reference($handlerId)));
       
   306             }
       
   307         }
       
   308 
       
   309         // Authentication listeners
       
   310         list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $authenticationProviders, $defaultProvider, $factories);
       
   311 
       
   312         $listeners = array_merge($listeners, $authListeners);
       
   313 
       
   314         // Access listener
       
   315         $listeners[] = new Reference('security.access_listener');
       
   316 
       
   317         // Switch user listener
       
   318         if (isset($firewall['switch_user'])) {
       
   319             $listeners[] = new Reference($this->createSwitchUserListener($container, $id, $firewall['switch_user'], $defaultProvider));
       
   320         }
       
   321 
       
   322         // Determine default entry point
       
   323         if (isset($firewall['entry_point'])) {
       
   324             $defaultEntryPoint = $firewall['entry_point'];
       
   325         }
       
   326 
       
   327         // Exception listener
       
   328         $exceptionListener = new Reference($this->createExceptionListener($container, $firewall, $id, $defaultEntryPoint));
       
   329 
       
   330         return array($matcher, $listeners, $exceptionListener);
       
   331     }
       
   332 
       
   333     private function createContextListener($container, $contextKey)
       
   334     {
       
   335         if (isset($this->contextListeners[$contextKey])) {
       
   336             return $this->contextListeners[$contextKey];
       
   337         }
       
   338 
       
   339         $listenerId = 'security.context_listener.'.count($this->contextListeners);
       
   340         $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.context_listener'));
       
   341         $listener->replaceArgument(2, $contextKey);
       
   342 
       
   343         return $this->contextListeners[$contextKey] = $listenerId;
       
   344     }
       
   345 
       
   346     private function createAuthenticationListeners($container, $id, $firewall, &$authenticationProviders, $defaultProvider, array $factories)
       
   347     {
       
   348         $listeners = array();
       
   349         $hasListeners = false;
       
   350         $defaultEntryPoint = null;
       
   351 
       
   352         foreach ($this->listenerPositions as $position) {
       
   353             foreach ($factories[$position] as $factory) {
       
   354                 $key = str_replace('-', '_', $factory->getKey());
       
   355 
       
   356                 if (isset($firewall[$key])) {
       
   357                     $userProvider = isset($firewall[$key]['provider']) ? $this->getUserProviderId($firewall[$key]['provider']) : $defaultProvider;
       
   358 
       
   359                     list($provider, $listenerId, $defaultEntryPoint) = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint);
       
   360 
       
   361                     $listeners[] = new Reference($listenerId);
       
   362                     $authenticationProviders[] = $provider;
       
   363                     $hasListeners = true;
       
   364                 }
       
   365             }
       
   366         }
       
   367 
       
   368         // Anonymous
       
   369         if (isset($firewall['anonymous'])) {
       
   370             $listenerId = 'security.authentication.listener.anonymous.'.$id;
       
   371             $container
       
   372                 ->setDefinition($listenerId, new DefinitionDecorator('security.authentication.listener.anonymous'))
       
   373                 ->replaceArgument(1, $firewall['anonymous']['key'])
       
   374             ;
       
   375 
       
   376             $listeners[] = new Reference($listenerId);
       
   377 
       
   378             $providerId = 'security.authentication.provider.anonymous.'.$id;
       
   379             $container
       
   380                 ->setDefinition($providerId, new DefinitionDecorator('security.authentication.provider.anonymous'))
       
   381                 ->replaceArgument(0, $firewall['anonymous']['key'])
       
   382             ;
       
   383 
       
   384             $authenticationProviders[] = $providerId;
       
   385             $hasListeners = true;
       
   386         }
       
   387 
       
   388         if (false === $hasListeners) {
       
   389             throw new \LogicException(sprintf('No authentication listener registered for firewall "%s".', $id));
       
   390         }
       
   391 
       
   392         return array($listeners, $defaultEntryPoint);
       
   393     }
       
   394 
       
   395     private function createEncoders($encoders, ContainerBuilder $container)
       
   396     {
       
   397         $encoderMap = array();
       
   398         foreach ($encoders as $class => $encoder) {
       
   399             $encoderMap[$class] = $this->createEncoder($encoder, $container);
       
   400         }
       
   401 
       
   402         $container
       
   403             ->getDefinition('security.encoder_factory.generic')
       
   404             ->setArguments(array($encoderMap))
       
   405         ;
       
   406     }
       
   407 
       
   408     private function createEncoder($config, ContainerBuilder $container)
       
   409     {
       
   410         // a custom encoder service
       
   411         if (isset($config['id'])) {
       
   412             return new Reference($config['id']);
       
   413         }
       
   414 
       
   415         // plaintext encoder
       
   416         if ('plaintext' === $config['algorithm']) {
       
   417             $arguments = array($config['ignore_case']);
       
   418 
       
   419             return array(
       
   420                 'class' => new Parameter('security.encoder.plain.class'),
       
   421                 'arguments' => $arguments,
       
   422             );
       
   423         }
       
   424 
       
   425         // message digest encoder
       
   426         $arguments = array(
       
   427             $config['algorithm'],
       
   428             $config['encode_as_base64'],
       
   429             $config['iterations'],
       
   430         );
       
   431 
       
   432         return array(
       
   433             'class' => new Parameter('security.encoder.digest.class'),
       
   434             'arguments' => $arguments,
       
   435         );
       
   436     }
       
   437 
       
   438     // Parses user providers and returns an array of their ids
       
   439     private function createUserProviders($config, ContainerBuilder $container)
       
   440     {
       
   441         $providerIds = array();
       
   442         foreach ($config['providers'] as $name => $provider) {
       
   443             $id = $this->createUserDaoProvider($name, $provider, $container);
       
   444             $providerIds[] = $id;
       
   445         }
       
   446 
       
   447         return $providerIds;
       
   448     }
       
   449 
       
   450     // Parses a <provider> tag and returns the id for the related user provider service
       
   451     private function createUserDaoProvider($name, $provider, ContainerBuilder $container, $master = true)
       
   452     {
       
   453         $name = $this->getUserProviderId(strtolower($name));
       
   454 
       
   455         // Existing DAO service provider
       
   456         if (isset($provider['id'])) {
       
   457             $container->setAlias($name, new Alias($provider['id'], false));
       
   458 
       
   459             return $provider['id'];
       
   460         }
       
   461 
       
   462         // Chain provider
       
   463         if ($provider['providers']) {
       
   464             $providers = array();
       
   465             foreach ($provider['providers'] as $providerName) {
       
   466                 $providers[] = new Reference($this->getUserProviderId(strtolower($providerName)));
       
   467             }
       
   468 
       
   469             $container
       
   470                 ->setDefinition($name, new DefinitionDecorator('security.user.provider.chain'))
       
   471                 ->addArgument($providers)
       
   472             ;
       
   473 
       
   474             return $name;
       
   475         }
       
   476 
       
   477         // Doctrine Entity DAO provider
       
   478         if (isset($provider['entity'])) {
       
   479             $container
       
   480                 ->setDefinition($name, new DefinitionDecorator('security.user.provider.entity'))
       
   481                 ->addArgument($provider['entity']['class'])
       
   482                 ->addArgument($provider['entity']['property'])
       
   483             ;
       
   484 
       
   485             return $name;
       
   486         }
       
   487 
       
   488         // In-memory DAO provider
       
   489         $definition = $container->setDefinition($name, new DefinitionDecorator('security.user.provider.in_memory'));
       
   490         foreach ($provider['users'] as $username => $user) {
       
   491             $userId = $name.'_'.$username;
       
   492 
       
   493             $container
       
   494                 ->setDefinition($userId, new DefinitionDecorator('security.user.provider.in_memory.user'))
       
   495                 ->setArguments(array($username, (string)$user['password'], $user['roles']))
       
   496             ;
       
   497 
       
   498             $definition->addMethodCall('createUser', array(new Reference($userId)));
       
   499         }
       
   500 
       
   501         return $name;
       
   502     }
       
   503 
       
   504     private function getUserProviderId($name)
       
   505     {
       
   506         return 'security.user.provider.concrete.'.$name;
       
   507     }
       
   508 
       
   509     private function createExceptionListener($container, $config, $id, $defaultEntryPoint)
       
   510     {
       
   511         $exceptionListenerId = 'security.exception_listener.'.$id;
       
   512         $listener = $container->setDefinition($exceptionListenerId, new DefinitionDecorator('security.exception_listener'));
       
   513         $listener->replaceArgument(3, null === $defaultEntryPoint ? null : new Reference($defaultEntryPoint));
       
   514 
       
   515         // access denied handler setup
       
   516         if (isset($config['access_denied_handler'])) {
       
   517             $listener->replaceArgument(5, new Reference($config['access_denied_handler']));
       
   518         } else if (isset($config['access_denied_url'])) {
       
   519             $listener->replaceArgument(4, $config['access_denied_url']);
       
   520         }
       
   521 
       
   522         return $exceptionListenerId;
       
   523     }
       
   524 
       
   525     private function createSwitchUserListener($container, $id, $config, $defaultProvider)
       
   526     {
       
   527         $userProvider = isset($config['provider']) ? $this->getUserProviderId($config['provider']) : $defaultProvider;
       
   528 
       
   529         $switchUserListenerId = 'security.authentication.switchuser_listener.'.$id;
       
   530         $listener = $container->setDefinition($switchUserListenerId, new DefinitionDecorator('security.authentication.switchuser_listener'));
       
   531         $listener->replaceArgument(1, new Reference($userProvider));
       
   532         $listener->replaceArgument(3, $id);
       
   533         $listener->replaceArgument(6, $config['parameter']);
       
   534         $listener->replaceArgument(7, $config['role']);
       
   535 
       
   536         return $switchUserListenerId;
       
   537     }
       
   538 
       
   539     private function createRequestMatcher($container, $path = null, $host = null, $methods = null, $ip = null, array $attributes = array())
       
   540     {
       
   541         $serialized = serialize(array($path, $host, $methods, $ip, $attributes));
       
   542         $id = 'security.request_matcher.'.md5($serialized).sha1($serialized);
       
   543 
       
   544         if (isset($this->requestMatchers[$id])) {
       
   545             return $this->requestMatchers[$id];
       
   546         }
       
   547 
       
   548         // only add arguments that are necessary
       
   549         $arguments = array($path, $host, $methods, $ip, $attributes);
       
   550         while (count($arguments) > 0 && !end($arguments)) {
       
   551             array_pop($arguments);
       
   552         }
       
   553 
       
   554         $container
       
   555             ->register($id, '%security.matcher.class%')
       
   556             ->setPublic(false)
       
   557             ->setArguments($arguments)
       
   558         ;
       
   559 
       
   560         return $this->requestMatchers[$id] = new Reference($id);
       
   561     }
       
   562 
       
   563     private function createListenerFactories(ContainerBuilder $container, $config)
       
   564     {
       
   565         if (null !== $this->factories) {
       
   566             return $this->factories;
       
   567         }
       
   568 
       
   569         // load service templates
       
   570         $c = new ContainerBuilder();
       
   571         $parameterBag = $container->getParameterBag();
       
   572 
       
   573         $locator = new FileLocator(__DIR__.'/../Resources/config');
       
   574         $resolver = new LoaderResolver(array(
       
   575             new XmlFileLoader($c, $locator),
       
   576             new YamlFileLoader($c, $locator),
       
   577             new PhpFileLoader($c, $locator),
       
   578         ));
       
   579         $loader = new DelegatingLoader($resolver);
       
   580 
       
   581         $loader->load('security_factories.xml');
       
   582 
       
   583         // load user-created listener factories
       
   584         foreach ($config['factories'] as $factory) {
       
   585             $loader->load($parameterBag->resolveValue($factory));
       
   586         }
       
   587 
       
   588         $tags = $c->findTaggedServiceIds('security.listener.factory');
       
   589 
       
   590         $factories = array();
       
   591         foreach ($this->listenerPositions as $position) {
       
   592             $factories[$position] = array();
       
   593         }
       
   594 
       
   595         foreach (array_keys($tags) as $tag) {
       
   596             $factory = $c->get($tag);
       
   597             $factories[$factory->getPosition()][] = $factory;
       
   598         }
       
   599 
       
   600         return $this->factories = $factories;
       
   601     }
       
   602 
       
   603 
       
   604     /**
       
   605      * Returns the base path for the XSD files.
       
   606      *
       
   607      * @return string The XSD base path
       
   608      */
       
   609     public function getXsdValidationBasePath()
       
   610     {
       
   611         return __DIR__.'/../Resources/config/schema';
       
   612     }
       
   613 
       
   614     public function getNamespace()
       
   615     {
       
   616         return 'http://symfony.com/schema/dic/security';
       
   617     }
       
   618 }
       
   619