vendor/symfony/security-bundle/DependencyInjection/Security/Factory/AbstractFactory.php line 53

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <[email protected]>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory;
  11. use Symfony\Component\Config\Definition\Builder\NodeDefinition;
  12. use Symfony\Component\DependencyInjection\ChildDefinition;
  13. use Symfony\Component\DependencyInjection\ContainerBuilder;
  14. use Symfony\Component\DependencyInjection\Reference;
  15. /**
  16.  * AbstractFactory is the base class for all classes inheriting from
  17.  * AbstractAuthenticationListener.
  18.  *
  19.  * @author Fabien Potencier <[email protected]>
  20.  * @author Lukas Kahwe Smith <[email protected]>
  21.  * @author Johannes M. Schmitt <[email protected]>
  22.  */
  23. abstract class AbstractFactory implements SecurityFactoryInterface
  24. {
  25.     protected $options = [
  26.         'check_path' => '/login_check',
  27.         'use_forward' => false,
  28.         'require_previous_session' => false,
  29.     ];
  30.     protected $defaultSuccessHandlerOptions = [
  31.         'always_use_default_target_path' => false,
  32.         'default_target_path' => '/',
  33.         'login_path' => '/login',
  34.         'target_path_parameter' => '_target_path',
  35.         'use_referer' => false,
  36.     ];
  37.     protected $defaultFailureHandlerOptions = [
  38.         'failure_path' => null,
  39.         'failure_forward' => false,
  40.         'login_path' => '/login',
  41.         'failure_path_parameter' => '_failure_path',
  42.     ];
  43.     public function create(ContainerBuilder $container$id$config$userProviderId$defaultEntryPointId)
  44.     {
  45.         // authentication provider
  46.         $authProviderId $this->createAuthProvider($container$id$config$userProviderId);
  47.         // authentication listener
  48.         $listenerId $this->createListener($container$id$config$userProviderId);
  49.         // add remember-me aware tag if requested
  50.         if ($this->isRememberMeAware($config)) {
  51.             $container
  52.                 ->getDefinition($listenerId)
  53.                 ->addTag('security.remember_me_aware', ['id' => $id'provider' => $userProviderId])
  54.             ;
  55.         }
  56.         // create entry point if applicable (optional)
  57.         $entryPointId $this->createEntryPoint($container$id$config$defaultEntryPointId);
  58.         return [$authProviderId$listenerId$entryPointId];
  59.     }
  60.     public function addConfiguration(NodeDefinition $node)
  61.     {
  62.         $builder $node->children();
  63.         $builder
  64.             ->scalarNode('provider')->end()
  65.             ->booleanNode('remember_me')->defaultTrue()->end()
  66.             ->scalarNode('success_handler')->end()
  67.             ->scalarNode('failure_handler')->end()
  68.         ;
  69.         foreach (array_merge($this->options$this->defaultSuccessHandlerOptions$this->defaultFailureHandlerOptions) as $name => $default) {
  70.             if (\is_bool($default)) {
  71.                 $builder->booleanNode($name)->defaultValue($default);
  72.             } else {
  73.                 $builder->scalarNode($name)->defaultValue($default);
  74.             }
  75.         }
  76.     }
  77.     final public function addOption(string $name$default null)
  78.     {
  79.         $this->options[$name] = $default;
  80.     }
  81.     /**
  82.      * Subclasses must return the id of a service which implements the
  83.      * AuthenticationProviderInterface.
  84.      *
  85.      * @param string $id             The unique id of the firewall
  86.      * @param array  $config         The options array for this listener
  87.      * @param string $userProviderId The id of the user provider
  88.      *
  89.      * @return string never null, the id of the authentication provider
  90.      */
  91.     abstract protected function createAuthProvider(ContainerBuilder $container$id$config$userProviderId);
  92.     /**
  93.      * Subclasses must return the id of the abstract listener template.
  94.      *
  95.      * Listener definitions should inherit from the AbstractAuthenticationListener
  96.      * like this:
  97.      *
  98.      *    <service id="my.listener.id"
  99.      *             class="My\Concrete\Classname"
  100.      *             parent="security.authentication.listener.abstract"
  101.      *             abstract="true" />
  102.      *
  103.      * In the above case, this method would return "my.listener.id".
  104.      *
  105.      * @return string
  106.      */
  107.     abstract protected function getListenerId();
  108.     /**
  109.      * Subclasses may create an entry point of their as they see fit. The
  110.      * default implementation does not change the default entry point.
  111.      *
  112.      * @param ContainerBuilder $container
  113.      * @param string           $id
  114.      * @param array            $config
  115.      * @param string|null      $defaultEntryPointId
  116.      *
  117.      * @return string|null the entry point id
  118.      */
  119.     protected function createEntryPoint($container$id$config$defaultEntryPointId)
  120.     {
  121.         return $defaultEntryPointId;
  122.     }
  123.     /**
  124.      * Subclasses may disable remember-me features for the listener, by
  125.      * always returning false from this method.
  126.      *
  127.      * @return bool Whether a possibly configured RememberMeServices should be set for this listener
  128.      */
  129.     protected function isRememberMeAware($config)
  130.     {
  131.         return $config['remember_me'];
  132.     }
  133.     protected function createListener($container$id$config$userProvider)
  134.     {
  135.         $listenerId $this->getListenerId();
  136.         $listener = new ChildDefinition($listenerId);
  137.         $listener->replaceArgument(4$id);
  138.         $listener->replaceArgument(5, new Reference($this->createAuthenticationSuccessHandler($container$id$config)));
  139.         $listener->replaceArgument(6, new Reference($this->createAuthenticationFailureHandler($container$id$config)));
  140.         $listener->replaceArgument(7array_intersect_key($config$this->options));
  141.         $listenerId .= '.'.$id;
  142.         $container->setDefinition($listenerId$listener);
  143.         return $listenerId;
  144.     }
  145.     protected function createAuthenticationSuccessHandler($container$id$config)
  146.     {
  147.         $successHandlerId $this->getSuccessHandlerId($id);
  148.         $options array_intersect_key($config$this->defaultSuccessHandlerOptions);
  149.         if (isset($config['success_handler'])) {
  150.             $successHandler $container->setDefinition($successHandlerId, new ChildDefinition('security.authentication.custom_success_handler'));
  151.             $successHandler->replaceArgument(0, new Reference($config['success_handler']));
  152.             $successHandler->replaceArgument(1$options);
  153.             $successHandler->replaceArgument(2$id);
  154.         } else {
  155.             $successHandler $container->setDefinition($successHandlerId, new ChildDefinition('security.authentication.success_handler'));
  156.             $successHandler->addMethodCall('setOptions', [$options]);
  157.             $successHandler->addMethodCall('setProviderKey', [$id]);
  158.         }
  159.         return $successHandlerId;
  160.     }
  161.     protected function createAuthenticationFailureHandler($container$id$config)
  162.     {
  163.         $id $this->getFailureHandlerId($id);
  164.         $options array_intersect_key($config$this->defaultFailureHandlerOptions);
  165.         if (isset($config['failure_handler'])) {
  166.             $failureHandler $container->setDefinition($id, new ChildDefinition('security.authentication.custom_failure_handler'));
  167.             $failureHandler->replaceArgument(0, new Reference($config['failure_handler']));
  168.             $failureHandler->replaceArgument(1$options);
  169.         } else {
  170.             $failureHandler $container->setDefinition($id, new ChildDefinition('security.authentication.failure_handler'));
  171.             $failureHandler->addMethodCall('setOptions', [$options]);
  172.         }
  173.         return $id;
  174.     }
  175.     protected function getSuccessHandlerId($id)
  176.     {
  177.         return 'security.authentication.success_handler.'.$id.'.'.str_replace('-''_'$this->getKey());
  178.     }
  179.     protected function getFailureHandlerId($id)
  180.     {
  181.         return 'security.authentication.failure_handler.'.$id.'.'.str_replace('-''_'$this->getKey());
  182.     }
  183. }