Skip to content

Commit

Permalink
[Security][Guard] Lazy load authenticators
Browse files Browse the repository at this point in the history
  • Loading branch information
chalasr committed Jan 31, 2017
1 parent b3b3dac commit b8a23de
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 16 deletions.
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory;

use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
Expand Down Expand Up @@ -62,11 +63,13 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider,
$authenticatorReferences[] = new Reference($authenticatorId);
}

$authenticators = new IteratorArgument($authenticatorReferences);

// configure the GuardAuthenticationFactory to have the dynamic constructor arguments
$providerId = 'security.authentication.provider.guard.'.$id;
$container
->setDefinition($providerId, new ChildDefinition('security.authentication.provider.guard'))
->replaceArgument(0, $authenticatorReferences)
->replaceArgument(0, $authenticators)
->replaceArgument(1, new Reference($userProvider))
->replaceArgument(2, $id)
->replaceArgument(3, new Reference('security.user_checker.'.$id))
Expand All @@ -76,7 +79,7 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider,
$listenerId = 'security.authentication.listener.guard.'.$id;
$listener = $container->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.guard'));
$listener->replaceArgument(2, $id);
$listener->replaceArgument(3, $authenticatorReferences);
$listener->replaceArgument(3, $authenticators);

// determine the entryPointId to use
$entryPointId = $this->determineEntryPoint($defaultEntryPoint, $config);
Expand Down
Expand Up @@ -13,6 +13,7 @@

use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\GuardAuthenticationFactory;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

Expand Down Expand Up @@ -106,15 +107,15 @@ public function testBasicCreate()

$providerDefinition = $container->getDefinition('security.authentication.provider.guard.my_firewall');
$this->assertEquals(array(
'index_0' => array(new Reference('authenticator123')),
'index_0' => new IteratorArgument(array(new Reference('authenticator123'))),
'index_1' => new Reference('my_user_provider'),
'index_2' => 'my_firewall',
'index_3' => new Reference('security.user_checker.my_firewall'),
), $providerDefinition->getArguments());

$listenerDefinition = $container->getDefinition('security.authentication.listener.guard.my_firewall');
$this->assertEquals('my_firewall', $listenerDefinition->getArgument(2));
$this->assertEquals(array(new Reference('authenticator123')), $listenerDefinition->getArgument(3));
$this->assertEquals(array(new Reference('authenticator123')), $listenerDefinition->getArgument(3)->getValues());
}

public function testExistingDefaultEntryPointUsed()
Expand Down
Expand Up @@ -39,13 +39,13 @@ class GuardAuthenticationListener implements ListenerInterface
private $rememberMeServices;

/**
* @param GuardAuthenticatorHandler $guardHandler The Guard handler
* @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
* @param string $providerKey The provider (i.e. firewall) key
* @param GuardAuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider
* @param LoggerInterface $logger A LoggerInterface instance
* @param GuardAuthenticatorHandler $guardHandler The Guard handler
* @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
* @param string $providerKey The provider (i.e. firewall) key
* @param iterable|GuardAuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider
* @param LoggerInterface $logger A LoggerInterface instance
*/
public function __construct(GuardAuthenticatorHandler $guardHandler, AuthenticationManagerInterface $authenticationManager, $providerKey, array $guardAuthenticators, LoggerInterface $logger = null)
public function __construct(GuardAuthenticatorHandler $guardHandler, AuthenticationManagerInterface $authenticationManager, $providerKey, $guardAuthenticators, LoggerInterface $logger = null)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
Expand All @@ -66,7 +66,13 @@ public function __construct(GuardAuthenticatorHandler $guardHandler, Authenticat
public function handle(GetResponseEvent $event)
{
if (null !== $this->logger) {
$this->logger->debug('Checking for guard authentication credentials.', array('firewall_key' => $this->providerKey, 'authenticators' => count($this->guardAuthenticators)));
$context = array('firewall_key' => $this->providerKey);

if ($this->guardAuthenticators instanceof \Countable || is_array($this->guardAuthenticators)) {
$context['authenticators'] = count($this->guardAuthenticators);
}

$this->logger->debug('Checking for guard authentication credentials.', $context);
}

foreach ($this->guardAuthenticators as $key => $guardAuthenticator) {
Expand Down
Expand Up @@ -40,12 +40,12 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
private $userChecker;

/**
* @param GuardAuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationListener
* @param UserProviderInterface $userProvider The user provider
* @param string $providerKey The provider (i.e. firewall) key
* @param UserCheckerInterface $userChecker
* @param iterable|GuardAuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationListener
* @param UserProviderInterface $userProvider The user provider
* @param string $providerKey The provider (i.e. firewall) key
* @param UserCheckerInterface $userChecker
*/
public function __construct(array $guardAuthenticators, UserProviderInterface $userProvider, $providerKey, UserCheckerInterface $userChecker)
public function __construct($guardAuthenticators, UserProviderInterface $userProvider, $providerKey, UserCheckerInterface $userChecker)
{
$this->guardAuthenticators = $guardAuthenticators;
$this->userProvider = $userProvider;
Expand Down

0 comments on commit b8a23de

Please sign in to comment.