Removed all mentions of 'guard' in the new system

This to remove confusion between the new system and Guard. When using the new
system, guard should not be installed. Guard did however influence the idea
behind the new system. Thus keeping the mentions of "guard" makes it confusing
to use the new system.
This commit is contained in:
Wouter de Jong 2020-02-06 15:41:40 +01:00
parent 999ec2795f
commit 7859977324
42 changed files with 419 additions and 316 deletions

View File

@ -73,7 +73,7 @@ class MainConfiguration implements ConfigurationInterface
->booleanNode('hide_user_not_found')->defaultTrue()->end() ->booleanNode('hide_user_not_found')->defaultTrue()->end()
->booleanNode('always_authenticate_before_granting')->defaultFalse()->end() ->booleanNode('always_authenticate_before_granting')->defaultFalse()->end()
->booleanNode('erase_credentials')->defaultTrue()->end() ->booleanNode('erase_credentials')->defaultTrue()->end()
->booleanNode('guard_authentication_manager')->defaultFalse()->end() ->booleanNode('enable_authenticator_manager')->defaultFalse()->info('Enables the new Symfony Security system based on Authenticators, all used authenticators must support this before enabling this.')->end()
->arrayNode('access_decision_manager') ->arrayNode('access_decision_manager')
->addDefaultsIfNotSet() ->addDefaultsIfNotSet()
->children() ->children()

View File

@ -19,7 +19,7 @@ use Symfony\Component\DependencyInjection\Parameter;
/** /**
* @author Wouter de Jong <wouter@wouterj.nl> * @author Wouter de Jong <wouter@wouterj.nl>
*/ */
class AnonymousFactory implements SecurityFactoryInterface, GuardFactoryInterface class AnonymousFactory implements SecurityFactoryInterface, AuthenticatorFactoryInterface
{ {
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint) public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
{ {
@ -42,7 +42,7 @@ class AnonymousFactory implements SecurityFactoryInterface, GuardFactoryInterfac
return [$providerId, $listenerId, $defaultEntryPoint]; return [$providerId, $listenerId, $defaultEntryPoint];
} }
public function createGuard(ContainerBuilder $container, string $id, array $config, ?string $userProviderId): string public function createAuthenticator(ContainerBuilder $container, string $id, array $config, ?string $userProviderId): string
{ {
if (null === $config['secret']) { if (null === $config['secret']) {
$config['secret'] = new Parameter('container.build_hash'); $config['secret'] = new Parameter('container.build_hash');

View File

@ -18,12 +18,12 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
* *
* @experimental in 5.1 * @experimental in 5.1
*/ */
interface GuardFactoryInterface interface AuthenticatorFactoryInterface
{ {
/** /**
* Creates the Guard service(s) for the provided configuration. * Creates the authenticator service(s) for the provided configuration.
* *
* @return string|string[] The Guard service ID(s) to be used by the firewall * @return string|string[] The authenticator service ID(s) to be used by the firewall
*/ */
public function createGuard(ContainerBuilder $container, string $id, array $config, ?string $userProviderId); public function createAuthenticator(ContainerBuilder $container, string $id, array $config, ?string $userProviderId);
} }

View File

@ -22,7 +22,7 @@ use Symfony\Component\DependencyInjection\Reference;
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com> * @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/ */
class FormLoginFactory extends AbstractFactory implements GuardFactoryInterface, EntryPointFactoryInterface class FormLoginFactory extends AbstractFactory implements AuthenticatorFactoryInterface, EntryPointFactoryInterface
{ {
public function __construct() public function __construct()
{ {
@ -97,7 +97,7 @@ class FormLoginFactory extends AbstractFactory implements GuardFactoryInterface,
return $entryPointId; return $entryPointId;
} }
public function createGuard(ContainerBuilder $container, string $id, array $config, ?string $userProviderId): string public function createAuthenticator(ContainerBuilder $container, string $id, array $config, ?string $userProviderId): string
{ {
$authenticatorId = 'security.authenticator.form_login.'.$id; $authenticatorId = 'security.authenticator.form_login.'.$id;
$defaultOptions = array_merge($this->defaultSuccessHandlerOptions, $this->options); $defaultOptions = array_merge($this->defaultSuccessHandlerOptions, $this->options);

View File

@ -21,7 +21,7 @@ use Symfony\Component\DependencyInjection\Reference;
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
*/ */
class HttpBasicFactory implements SecurityFactoryInterface, GuardFactoryInterface class HttpBasicFactory implements SecurityFactoryInterface, AuthenticatorFactoryInterface
{ {
public function create(ContainerBuilder $container, string $id, array $config, string $userProvider, ?string $defaultEntryPoint) public function create(ContainerBuilder $container, string $id, array $config, string $userProvider, ?string $defaultEntryPoint)
{ {
@ -46,7 +46,7 @@ class HttpBasicFactory implements SecurityFactoryInterface, GuardFactoryInterfac
return [$provider, $listenerId, $entryPointId]; return [$provider, $listenerId, $entryPointId];
} }
public function createGuard(ContainerBuilder $container, string $id, array $config, ?string $userProviderId): string public function createAuthenticator(ContainerBuilder $container, string $id, array $config, ?string $userProviderId): string
{ {
$authenticatorId = 'security.authenticator.http_basic.'.$id; $authenticatorId = 'security.authenticator.http_basic.'.$id;
$container $container

View File

@ -11,8 +11,8 @@
namespace Symfony\Bundle\SecurityBundle\DependencyInjection; namespace Symfony\Bundle\SecurityBundle\DependencyInjection;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AuthenticatorFactoryInterface;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\EntryPointFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\EntryPointFactoryInterface;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\GuardFactoryInterface;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\RememberMeFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\RememberMeFactory;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface;
@ -54,7 +54,7 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
private $userProviderFactories = []; private $userProviderFactories = [];
private $statelessFirewallKeys = []; private $statelessFirewallKeys = [];
private $guardAuthenticationManagerEnabled = false; private $authenticatorManagerEnabled = false;
public function __construct() public function __construct()
{ {
@ -139,7 +139,7 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
$container->setParameter('security.access.always_authenticate_before_granting', $config['always_authenticate_before_granting']); $container->setParameter('security.access.always_authenticate_before_granting', $config['always_authenticate_before_granting']);
$container->setParameter('security.authentication.hide_user_not_found', $config['hide_user_not_found']); $container->setParameter('security.authentication.hide_user_not_found', $config['hide_user_not_found']);
if ($this->guardAuthenticationManagerEnabled = $config['guard_authentication_manager']) { if ($this->authenticatorManagerEnabled = $config['enable_authenticator_manager']) {
$loader->load('authenticators.xml'); $loader->load('authenticators.xml');
} }
@ -150,6 +150,11 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
$container->getDefinition('security.authentication.guard_handler') $container->getDefinition('security.authentication.guard_handler')
->replaceArgument(2, $this->statelessFirewallKeys); ->replaceArgument(2, $this->statelessFirewallKeys);
if ($this->authenticatorManagerEnabled) {
$container->getDefinition('security.authenticator_handler')
->replaceArgument(2, $this->statelessFirewallKeys);
}
if ($config['encoders']) { if ($config['encoders']) {
$this->createEncoders($config['encoders'], $container); $this->createEncoders($config['encoders'], $container);
} }
@ -267,8 +272,8 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
return new Reference($id); return new Reference($id);
}, array_unique($authenticationProviders)); }, array_unique($authenticationProviders));
$authenticationManagerId = 'security.authentication.manager.provider'; $authenticationManagerId = 'security.authentication.manager.provider';
if ($this->guardAuthenticationManagerEnabled) { if ($this->authenticatorManagerEnabled) {
$authenticationManagerId = 'security.authentication.manager.guard'; $authenticationManagerId = 'security.authentication.manager.authenticator';
$container->setAlias('security.authentication.manager', new Alias($authenticationManagerId)); $container->setAlias('security.authentication.manager', new Alias($authenticationManagerId));
} }
$container $container
@ -418,7 +423,7 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
// Determine default entry point // Determine default entry point
$configuredEntryPoint = isset($firewall['entry_point']) ? $firewall['entry_point'] : null; $configuredEntryPoint = isset($firewall['entry_point']) ? $firewall['entry_point'] : null;
if ($this->guardAuthenticationManagerEnabled) { if ($this->authenticatorManagerEnabled) {
// Remember me listener (must be before calling createAuthenticationListeners() to inject remember me services) // Remember me listener (must be before calling createAuthenticationListeners() to inject remember me services)
$container $container
->setDefinition('security.listener.remember_me.'.$id, new ChildDefinition('security.listener.remember_me')) ->setDefinition('security.listener.remember_me.'.$id, new ChildDefinition('security.listener.remember_me'))
@ -434,10 +439,10 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
$authenticationProviders = array_merge($authenticationProviders, $firewallAuthenticationProviders); $authenticationProviders = array_merge($authenticationProviders, $firewallAuthenticationProviders);
if ($this->guardAuthenticationManagerEnabled) { if ($this->authenticatorManagerEnabled) {
// guard authentication manager listener // authenticator manager listener
$container $container
->setDefinition('security.firewall.guard.'.$id.'.locator', new ChildDefinition('security.firewall.guard.locator')) ->setDefinition('security.firewall.authenticator.'.$id.'.locator', new ChildDefinition('security.firewall.authenticator.locator'))
->setArguments([array_map(function ($id) { ->setArguments([array_map(function ($id) {
return new Reference($id); return new Reference($id);
}, $firewallAuthenticationProviders)]) }, $firewallAuthenticationProviders)])
@ -445,13 +450,13 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
; ;
$container $container
->setDefinition('security.firewall.guard.'.$id, new ChildDefinition('security.firewall.guard')) ->setDefinition('security.firewall.authenticator.'.$id, new ChildDefinition('security.firewall.authenticator'))
->replaceArgument(2, new Reference('security.firewall.guard.'.$id.'.locator')) ->replaceArgument(2, new Reference('security.firewall.authenticator.'.$id.'.locator'))
->replaceArgument(3, $id) ->replaceArgument(3, $id)
->addTag('kernel.event_listener', ['event' => KernelEvents::REQUEST]) ->addTag('kernel.event_listener', ['event' => KernelEvents::REQUEST])
; ;
$listeners[] = new Reference('security.firewall.guard.'.$id); $listeners[] = new Reference('security.firewall.authenticator.'.$id);
} }
$config->replaceArgument(7, $configuredEntryPoint ?: $defaultEntryPoint); $config->replaceArgument(7, $configuredEntryPoint ?: $defaultEntryPoint);
@ -515,12 +520,12 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
if (isset($firewall[$key])) { if (isset($firewall[$key])) {
$userProvider = $this->getUserProvider($container, $id, $firewall, $key, $defaultProvider, $providerIds, $contextListenerId); $userProvider = $this->getUserProvider($container, $id, $firewall, $key, $defaultProvider, $providerIds, $contextListenerId);
if ($this->guardAuthenticationManagerEnabled) { if ($this->authenticatorManagerEnabled) {
if (!$factory instanceof GuardFactoryInterface) { if (!$factory instanceof AuthenticatorFactoryInterface) {
throw new InvalidConfigurationException(sprintf('Cannot configure GuardAuthenticationManager as %s authentication does not support it, set security.guard_authentication_manager to `false`.', $key)); throw new InvalidConfigurationException(sprintf('Cannot configure AuthenticatorManager as "%s" authentication does not support it, set "security.enable_authenticator_manager" to `false`.', $key));
} }
$authenticators = $factory->createGuard($container, $id, $firewall[$key], $userProvider); $authenticators = $factory->createAuthenticator($container, $id, $firewall[$key], $userProvider);
if (\is_array($authenticators)) { if (\is_array($authenticators)) {
foreach ($authenticators as $i => $authenticator) { foreach ($authenticators as $i => $authenticator) {
$authenticationProviders[$id.'_'.$key.$i] = $authenticator; $authenticationProviders[$id.'_'.$key.$i] = $authenticator;

View File

@ -16,32 +16,32 @@ use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; use Symfony\Component\Security\Http\Authentication\AuthenticatorHandler;
use Symfony\Component\Security\Http\Firewall\GuardManagerListener; use Symfony\Component\Security\Http\Firewall\AuthenticatorManagerListener;
/** /**
* @author Wouter de Jong <wouter@wouterj.nl> * @author Wouter de Jong <wouter@wouterj.nl>
* *
* @experimental in 5.1 * @experimental in 5.1
*/ */
class LazyGuardManagerListener extends GuardManagerListener class LazyAuthenticatorManagerListener extends AuthenticatorManagerListener
{ {
private $guardLocator; private $guardLocator;
public function __construct( public function __construct(
AuthenticationManagerInterface $authenticationManager, AuthenticationManagerInterface $authenticationManager,
GuardAuthenticatorHandler $guardHandler, AuthenticatorHandler $authenticatorHandler,
ServiceLocator $guardLocator, ServiceLocator $guardLocator,
string $providerKey, string $providerKey,
EventDispatcherInterface $eventDispatcher, EventDispatcherInterface $eventDispatcher,
?LoggerInterface $logger = null ?LoggerInterface $logger = null
) { ) {
parent::__construct($authenticationManager, $guardHandler, [], $providerKey, $eventDispatcher, $logger); parent::__construct($authenticationManager, $authenticatorHandler, [], $providerKey, $eventDispatcher, $logger);
$this->guardLocator = $guardLocator; $this->guardLocator = $guardLocator;
} }
protected function getSupportingGuardAuthenticators(Request $request): array protected function getSupportingAuthenticators(Request $request): array
{ {
$guardAuthenticators = []; $guardAuthenticators = [];
foreach ($this->guardLocator->getProvidedServices() as $key => $type) { foreach ($this->guardLocator->getProvidedServices() as $key => $type) {

View File

@ -4,17 +4,28 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd"> xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
<services> <services>
<service id="security.firewall.guard.locator" <service id="security.authenticator_handler"
class="Symfony\Component\Security\Http\Authentication\AuthenticatorHandler"
>
<argument type="service" id="security.token_storage" />
<argument type="service" id="event_dispatcher" on-invalid="null" />
<argument /> <!-- stateless firewall keys -->
<call method="setSessionAuthenticationStrategy">
<argument type="service" id="security.authentication.session_strategy" />
</call>
</service>
<service id="security.firewall.authenticator.locator"
class="Symfony\Component\DependencyInjection\ServiceLocator" class="Symfony\Component\DependencyInjection\ServiceLocator"
abstract="true" /> abstract="true" />
<service id="security.firewall.guard" <service id="security.firewall.authenticator"
class="Symfony\Bundle\SecurityBundle\EventListener\LazyGuardManagerListener" class="Symfony\Bundle\SecurityBundle\EventListener\LazyAuthenticatorManagerListener"
abstract="true"> abstract="true">
<tag name="monolog.logger" channel="security" /> <tag name="monolog.logger" channel="security" />
<argument type="service" id="security.authentication.manager" /> <argument type="service" id="security.authentication.manager" />
<argument type="service" id="security.authentication.guard_handler" /> <argument type="service" id="security.authenticator_handler" />
<argument/> <!-- guard authenticator locator --> <argument/> <!-- authenticator locator -->
<argument/> <!-- provider key --> <argument/> <!-- provider key -->
<argument type="service" id="event_dispatcher" /> <argument type="service" id="event_dispatcher" />
<argument type="service" id="logger" on-invalid="null" /> <argument type="service" id="logger" on-invalid="null" />
@ -48,7 +59,7 @@
<!-- Authenticators --> <!-- Authenticators -->
<service id="security.authenticator.http_basic" <service id="security.authenticator.http_basic"
class="Symfony\Component\Security\Http\Authentication\Authenticator\HttpBasicAuthenticator" class="Symfony\Component\Security\Http\Authenticator\HttpBasicAuthenticator"
abstract="true"> abstract="true">
<argument type="abstract">realm name</argument> <argument type="abstract">realm name</argument>
<argument type="abstract">user provider</argument> <argument type="abstract">user provider</argument>
@ -57,7 +68,7 @@
</service> </service>
<service id="security.authenticator.form_login" <service id="security.authenticator.form_login"
class="Symfony\Component\Security\Http\Authentication\Authenticator\FormLoginAuthenticator" class="Symfony\Component\Security\Http\Authenticator\FormLoginAuthenticator"
abstract="true"> abstract="true">
<argument type="service" id="security.http_utils" /> <argument type="service" id="security.http_utils" />
<argument /> <!-- csrf token generator --> <argument /> <!-- csrf token generator -->
@ -66,7 +77,7 @@
</service> </service>
<service id="security.authenticator.anonymous" <service id="security.authenticator.anonymous"
class="Symfony\Component\Security\Http\Authentication\Authenticator\AnonymousAuthenticator" class="Symfony\Component\Security\Http\Authenticator\AnonymousAuthenticator"
abstract="true"> abstract="true">
<argument type="abstract">secret</argument> <argument type="abstract">secret</argument>
<argument type="service" id="security.token_storage" /> <argument type="service" id="security.token_storage" />

View File

@ -8,7 +8,7 @@
<defaults public="false" /> <defaults public="false" />
<service id="security.authentication.guard_handler" <service id="security.authentication.guard_handler"
class="Symfony\Component\Security\Guard\GuardAuthenticatorHandler" class="Symfony\Component\Security\Guard\GuardHandler"
> >
<argument type="service" id="security.token_storage" /> <argument type="service" id="security.token_storage" />
<argument type="service" id="event_dispatcher" on-invalid="null" /> <argument type="service" id="event_dispatcher" on-invalid="null" />
@ -17,8 +17,8 @@
<argument type="service" id="security.authentication.session_strategy" /> <argument type="service" id="security.authentication.session_strategy" />
</call> </call>
</service> </service>
<service id="Symfony\Component\Security\Guard\GuardAuthenticatorHandler" alias="security.authentication.guard_handler" /> <service id="AuthenticatorHandler" alias="security.authentication.guard_handler" />
<!-- See GuardAuthenticationFactory --> <!-- See GuardAuthenticationFactory -->
<service id="security.authentication.provider.guard" <service id="security.authentication.provider.guard"

View File

@ -52,8 +52,8 @@
<argument type="service" id="event_dispatcher" /> <argument type="service" id="event_dispatcher" />
</call> </call>
</service> </service>
<service id="security.authentication.manager.guard" class="Symfony\Component\Security\Http\Authentication\GuardAuthenticationManager"> <service id="security.authentication.manager.authenticator" class="Symfony\Component\Security\Http\Authentication\AuthenticatorManager">
<argument /> <!-- guard authenticators --> <argument /> <!-- authenticators -->
<argument type="service" id="event_dispatcher" /> <argument type="service" id="event_dispatcher" />
<argument>%security.authentication.manager.erase_credentials%</argument> <argument>%security.authentication.manager.erase_credentials%</argument>
<call method="setEventDispatcher"> <call method="setEventDispatcher">

View File

@ -5,12 +5,12 @@ namespace Symfony\Component\Security\Core\Tests\Authentication\Authenticator;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\Authenticator\HttpBasicAuthenticator;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface; use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException; use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Authenticator\HttpBasicAuthenticator;
class HttpBasicAuthenticatorTest extends TestCase class HttpBasicAuthenticatorTest extends TestCase
{ {
@ -39,8 +39,8 @@ class HttpBasicAuthenticatorTest extends TestCase
'PHP_AUTH_PW' => 'ThePassword', 'PHP_AUTH_PW' => 'ThePassword',
]); ]);
$guard = new HttpBasicAuthenticator('test', $this->userProvider, $this->encoderFactory); $authenticator = new HttpBasicAuthenticator('test', $this->userProvider, $this->encoderFactory);
$credentials = $guard->getCredentials($request); $credentials = $authenticator->getCredentials($request);
$this->assertEquals([ $this->assertEquals([
'username' => 'TheUsername', 'username' => 'TheUsername',
'password' => 'ThePassword', 'password' => 'ThePassword',
@ -55,7 +55,7 @@ class HttpBasicAuthenticatorTest extends TestCase
->with('TheUsername') ->with('TheUsername')
->willReturn($mockedUser); ->willReturn($mockedUser);
$user = $guard->getUser($credentials, $this->userProvider); $user = $authenticator->getUser($credentials, $this->userProvider);
$this->assertSame($mockedUser, $user); $this->assertSame($mockedUser, $user);
$this->encoder $this->encoder
@ -64,14 +64,14 @@ class HttpBasicAuthenticatorTest extends TestCase
->with('ThePassword', 'ThePassword', null) ->with('ThePassword', 'ThePassword', null)
->willReturn(true); ->willReturn(true);
$checkCredentials = $guard->checkCredentials($credentials, $user); $checkCredentials = $authenticator->checkCredentials($credentials, $user);
$this->assertTrue($checkCredentials); $this->assertTrue($checkCredentials);
} }
/** @dataProvider provideInvalidPasswords */ /** @dataProvider provideInvalidPasswords */
public function testInvalidPassword($presentedPassword, $exceptionMessage) public function testInvalidPassword($presentedPassword, $exceptionMessage)
{ {
$guard = new HttpBasicAuthenticator('test', $this->userProvider, $this->encoderFactory); $authenticator = new HttpBasicAuthenticator('test', $this->userProvider, $this->encoderFactory);
$this->encoder $this->encoder
->expects($this->any()) ->expects($this->any())
@ -81,7 +81,7 @@ class HttpBasicAuthenticatorTest extends TestCase
$this->expectException(BadCredentialsException::class); $this->expectException(BadCredentialsException::class);
$this->expectExceptionMessage($exceptionMessage); $this->expectExceptionMessage($exceptionMessage);
$guard->checkCredentials([ $authenticator->checkCredentials([
'username' => 'TheUsername', 'username' => 'TheUsername',
'password' => $presentedPassword, 'password' => $presentedPassword,
], $this->getMockBuilder(UserInterface::class)->getMock()); ], $this->getMockBuilder(UserInterface::class)->getMock());
@ -100,8 +100,8 @@ class HttpBasicAuthenticatorTest extends TestCase
{ {
$request = new Request([], [], [], [], [], $serverParameters); $request = new Request([], [], [], [], [], $serverParameters);
$guard = new HttpBasicAuthenticator('test', $this->userProvider, $this->encoderFactory); $authenticator = new HttpBasicAuthenticator('test', $this->userProvider, $this->encoderFactory);
$this->assertFalse($guard->supports($request)); $this->assertFalse($authenticator->supports($request));
} }
public function provideMissingHttpBasicServerParameters() public function provideMissingHttpBasicServerParameters()

View File

@ -16,14 +16,12 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticationGuardToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Guard\AuthenticatorInterface; use Symfony\Component\Security\Guard\AuthenticatorInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; use Symfony\Component\Security\Guard\GuardHandler;
use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken as GuardPreAuthenticationGuardToken; use Symfony\Component\Security\Guard\Token\PreAuthenticationToken as GuardPreAuthenticationGuardToken;
use Symfony\Component\Security\Http\Firewall\AbstractListener; use Symfony\Component\Security\Http\Firewall\AbstractListener;
use Symfony\Component\Security\Http\Firewall\GuardManagerListenerTrait;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
/** /**
@ -36,12 +34,12 @@ use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
*/ */
class GuardAuthenticationListener extends AbstractListener class GuardAuthenticationListener extends AbstractListener
{ {
use GuardManagerListenerTrait; use AuthenticatorManagerListenerTrait;
private $guardHandler; private $guardHandler;
private $authenticationManager; private $authenticationManager;
private $providerKey; private $providerKey;
private $guardAuthenticators; private $authenticators;
private $logger; private $logger;
private $rememberMeServices; private $rememberMeServices;
@ -49,7 +47,7 @@ class GuardAuthenticationListener extends AbstractListener
* @param string $providerKey The provider (i.e. firewall) key * @param string $providerKey The provider (i.e. firewall) key
* @param iterable|AuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider * @param iterable|AuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider
*/ */
public function __construct(GuardAuthenticatorHandler $guardHandler, AuthenticationManagerInterface $authenticationManager, string $providerKey, iterable $guardAuthenticators, LoggerInterface $logger = null) public function __construct(GuardHandler $guardHandler, AuthenticationManagerInterface $authenticationManager, string $providerKey, iterable $guardAuthenticators, LoggerInterface $logger = null)
{ {
if (empty($providerKey)) { if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.'); throw new \InvalidArgumentException('$providerKey must not be empty.');
@ -58,7 +56,7 @@ class GuardAuthenticationListener extends AbstractListener
$this->guardHandler = $guardHandler; $this->guardHandler = $guardHandler;
$this->authenticationManager = $authenticationManager; $this->authenticationManager = $authenticationManager;
$this->providerKey = $providerKey; $this->providerKey = $providerKey;
$this->guardAuthenticators = $guardAuthenticators; $this->authenticators = $guardAuthenticators;
$this->logger = $logger; $this->logger = $logger;
} }
@ -70,14 +68,14 @@ class GuardAuthenticationListener extends AbstractListener
if (null !== $this->logger) { if (null !== $this->logger) {
$context = ['firewall_key' => $this->providerKey]; $context = ['firewall_key' => $this->providerKey];
if ($this->guardAuthenticators instanceof \Countable || \is_array($this->guardAuthenticators)) { if ($this->authenticators instanceof \Countable || \is_array($this->authenticators)) {
$context['authenticators'] = \count($this->guardAuthenticators); $context['authenticators'] = \count($this->authenticators);
} }
$this->logger->debug('Checking for guard authentication credentials.', $context); $this->logger->debug('Checking for guard authentication credentials.', $context);
} }
$guardAuthenticators = $this->getSupportingGuardAuthenticators($request); $guardAuthenticators = $this->getSupportingAuthenticators($request);
if (!$guardAuthenticators) { if (!$guardAuthenticators) {
return false; return false;
} }
@ -143,7 +141,7 @@ class GuardAuthenticationListener extends AbstractListener
} }
// create a token with the unique key, so that the provider knows which authenticator to use // create a token with the unique key, so that the provider knows which authenticator to use
$token = $this->createPreAuthenticatedToken($credentials, $uniqueGuardKey, $this->providerKey); $token = new GuardPreAuthenticationGuardToken($credentials, $uniqueGuardKey, $this->providerKey);
if (null !== $this->logger) { if (null !== $this->logger) {
$this->logger->debug('Passing guard token information to the GuardAuthenticationProvider', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)]); $this->logger->debug('Passing guard token information to the GuardAuthenticationProvider', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)]);
@ -220,9 +218,4 @@ class GuardAuthenticationListener extends AbstractListener
$this->rememberMeServices->loginSuccess($request, $response, $token); $this->rememberMeServices->loginSuccess($request, $response, $token);
} }
protected function createPreAuthenticatedToken($credentials, string $uniqueGuardKey, string $providerKey): PreAuthenticationGuardToken
{
return new GuardPreAuthenticationGuardToken($credentials, $uniqueGuardKey, $providerKey);
}
} }

View File

@ -11,7 +11,7 @@
namespace Symfony\Component\Security\Guard; namespace Symfony\Component\Security\Guard;
use Symfony\Component\Security\Http\Authentication\GuardAuthenticatorHandler as CoreAuthenticatorHandlerAlias; use Symfony\Component\Security\Http\Authentication\AuthenticatorHandler;
/** /**
* A utility class that does much of the *work* during the guard authentication process. * A utility class that does much of the *work* during the guard authentication process.
@ -23,6 +23,6 @@ use Symfony\Component\Security\Http\Authentication\GuardAuthenticatorHandler as
* *
* @final * @final
*/ */
class GuardAuthenticatorHandler extends CoreAuthenticatorHandlerAlias class GuardHandler extends AuthenticatorHandler
{ {
} }

View File

@ -19,7 +19,6 @@ use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface; use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\Authentication\GuardAuthenticationManagerTrait;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
@ -29,7 +28,8 @@ use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AuthenticatorInterface; use Symfony\Component\Security\Guard\AuthenticatorInterface;
use Symfony\Component\Security\Guard\Token\GuardTokenInterface; use Symfony\Component\Security\Guard\Token\GuardTokenInterface;
use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; use Symfony\Component\Security\Guard\Token\PreAuthenticationToken;
use Symfony\Component\Security\Http\Authentication\AuthenticatorManagerTrait;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
/** /**
@ -40,12 +40,12 @@ use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
*/ */
class GuardAuthenticationProvider implements AuthenticationProviderInterface class GuardAuthenticationProvider implements AuthenticationProviderInterface
{ {
use GuardAuthenticationManagerTrait; use AuthenticatorManagerTrait;
/** /**
* @var AuthenticatorInterface[] * @var AuthenticatorInterface[]
*/ */
private $guardAuthenticators; private $authenticators;
private $userProvider; private $userProvider;
private $providerKey; private $providerKey;
private $userChecker; private $userChecker;
@ -58,7 +58,7 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
*/ */
public function __construct(iterable $guardAuthenticators, UserProviderInterface $userProvider, string $providerKey, UserCheckerInterface $userChecker, UserPasswordEncoderInterface $passwordEncoder = null) public function __construct(iterable $guardAuthenticators, UserProviderInterface $userProvider, string $providerKey, UserCheckerInterface $userChecker, UserPasswordEncoderInterface $passwordEncoder = null)
{ {
$this->guardAuthenticators = $guardAuthenticators; $this->authenticators = $guardAuthenticators;
$this->userProvider = $userProvider; $this->userProvider = $userProvider;
$this->providerKey = $providerKey; $this->providerKey = $providerKey;
$this->userChecker = $userChecker; $this->userChecker = $userChecker;
@ -78,7 +78,7 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
throw new \InvalidArgumentException('GuardAuthenticationProvider only supports GuardTokenInterface.'); throw new \InvalidArgumentException('GuardAuthenticationProvider only supports GuardTokenInterface.');
} }
if (!$token instanceof PreAuthenticationGuardToken) { if (!$token instanceof PreAuthenticationToken) {
/* /*
* The listener *only* passes PreAuthenticationGuardToken instances. * The listener *only* passes PreAuthenticationGuardToken instances.
* This means that an authenticated token (e.g. PostAuthenticationGuardToken) * This means that an authenticated token (e.g. PostAuthenticationGuardToken)
@ -101,7 +101,7 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
$guardAuthenticator = $this->findOriginatingAuthenticator($token); $guardAuthenticator = $this->findOriginatingAuthenticator($token);
if (null === $guardAuthenticator) { if (null === $guardAuthenticator) {
throw new AuthenticationException(sprintf('Token with provider key "%s" did not originate from any of the guard authenticators of provider "%s".', $token->getGuardProviderKey(), $this->providerKey)); throw new AuthenticationException(sprintf('Token with provider key "%s" did not originate from any of the guard authenticators of provider "%s".', $token->getAuthenticatorKey(), $this->providerKey));
} }
return $this->authenticateViaGuard($guardAuthenticator, $token, $this->providerKey); return $this->authenticateViaGuard($guardAuthenticator, $token, $this->providerKey);
@ -109,7 +109,7 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
public function supports(TokenInterface $token) public function supports(TokenInterface $token)
{ {
if ($token instanceof PreAuthenticationGuardToken) { if ($token instanceof PreAuthenticationToken) {
return null !== $this->findOriginatingAuthenticator($token); return null !== $this->findOriginatingAuthenticator($token);
} }
@ -121,12 +121,12 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
$this->rememberMeServices = $rememberMeServices; $this->rememberMeServices = $rememberMeServices;
} }
protected function getGuardKey(string $key): string protected function getAuthenticatorKey(string $key): string
{ {
return $this->providerKey.'_'.$key; return $this->providerKey.'_'.$key;
} }
private function authenticateViaGuard(AuthenticatorInterface $guardAuthenticator, \Symfony\Component\Security\Core\Authentication\Token\PreAuthenticationGuardToken $token, string $providerKey): TokenInterface private function authenticateViaGuard(AuthenticatorInterface $guardAuthenticator, \Symfony\Component\Security\Http\Authenticator\Token\PreAuthenticationToken $token, string $providerKey): TokenInterface
{ {
// get the user from the GuardAuthenticator // get the user from the GuardAuthenticator
$user = $guardAuthenticator->getUser($token->getCredentials(), $this->userProvider); $user = $guardAuthenticator->getUser($token->getCredentials(), $this->userProvider);

View File

@ -18,7 +18,7 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Guard\AuthenticatorInterface; use Symfony\Component\Security\Guard\AuthenticatorInterface;
use Symfony\Component\Security\Guard\Firewall\GuardAuthenticationListener; use Symfony\Component\Security\Guard\Firewall\GuardAuthenticationListener;
use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; use Symfony\Component\Security\Guard\Token\PreAuthenticationToken;
/** /**
* @author Ryan Weaver <weaverryan@gmail.com> * @author Ryan Weaver <weaverryan@gmail.com>
@ -53,7 +53,7 @@ class GuardAuthenticationListenerTest extends TestCase
// a clone of the token that should be created internally // a clone of the token that should be created internally
$uniqueGuardKey = 'my_firewall_0'; $uniqueGuardKey = 'my_firewall_0';
$nonAuthedToken = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey); $nonAuthedToken = new PreAuthenticationToken($credentials, $uniqueGuardKey);
$this->authenticationManager $this->authenticationManager
->expects($this->once()) ->expects($this->once())
@ -266,7 +266,9 @@ class GuardAuthenticationListenerTest extends TestCase
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
$this->guardAuthenticatorHandler = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorHandler') $this->guardAuthenticatorHandler = $this->getMockBuilder(
'Symfony\Component\Security\Guard\GuardHandler'
)
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();

View File

@ -18,7 +18,7 @@ use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInt
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Guard\AuthenticatorInterface; use Symfony\Component\Security\Guard\AuthenticatorInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; use Symfony\Component\Security\Guard\GuardHandler;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents; use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
@ -47,7 +47,7 @@ class GuardAuthenticatorHandlerTest extends TestCase
->with($this->equalTo($loginEvent), $this->equalTo(SecurityEvents::INTERACTIVE_LOGIN)) ->with($this->equalTo($loginEvent), $this->equalTo(SecurityEvents::INTERACTIVE_LOGIN))
; ;
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); $handler = new GuardHandler($this->tokenStorage, $this->dispatcher);
$handler->authenticateWithToken($this->token, $this->request); $handler->authenticateWithToken($this->token, $this->request);
} }
@ -60,7 +60,7 @@ class GuardAuthenticatorHandlerTest extends TestCase
->with($this->request, $this->token, $providerKey) ->with($this->request, $this->token, $providerKey)
->willReturn($response); ->willReturn($response);
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); $handler = new GuardHandler($this->tokenStorage, $this->dispatcher);
$actualResponse = $handler->handleAuthenticationSuccess($this->token, $this->request, $this->guardAuthenticator, $providerKey); $actualResponse = $handler->handleAuthenticationSuccess($this->token, $this->request, $this->guardAuthenticator, $providerKey);
$this->assertSame($response, $actualResponse); $this->assertSame($response, $actualResponse);
} }
@ -79,7 +79,7 @@ class GuardAuthenticatorHandlerTest extends TestCase
->with($this->request, $authException) ->with($this->request, $authException)
->willReturn($response); ->willReturn($response);
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); $handler = new GuardHandler($this->tokenStorage, $this->dispatcher);
$actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator, 'firewall_provider_key'); $actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator, 'firewall_provider_key');
$this->assertSame($response, $actualResponse); $this->assertSame($response, $actualResponse);
} }
@ -100,7 +100,7 @@ class GuardAuthenticatorHandlerTest extends TestCase
->with($this->request, $authException) ->with($this->request, $authException)
->willReturn($response); ->willReturn($response);
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); $handler = new GuardHandler($this->tokenStorage, $this->dispatcher);
$actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator, $actualProviderKey); $actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator, $actualProviderKey);
$this->assertSame($response, $actualResponse); $this->assertSame($response, $actualResponse);
} }
@ -124,7 +124,7 @@ class GuardAuthenticatorHandlerTest extends TestCase
->method('setToken') ->method('setToken')
->with($this->token); ->with($this->token);
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); $handler = new GuardHandler($this->tokenStorage, $this->dispatcher);
$handler->authenticateWithToken($this->token, $this->request); $handler->authenticateWithToken($this->token, $this->request);
} }
@ -136,7 +136,7 @@ class GuardAuthenticatorHandlerTest extends TestCase
->method('onAuthentication') ->method('onAuthentication')
->with($this->request, $this->token); ->with($this->request, $this->token);
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); $handler = new GuardHandler($this->tokenStorage, $this->dispatcher);
$handler->setSessionAuthenticationStrategy($this->sessionStrategy); $handler->setSessionAuthenticationStrategy($this->sessionStrategy);
$handler->authenticateWithToken($this->token, $this->request); $handler->authenticateWithToken($this->token, $this->request);
} }
@ -148,7 +148,7 @@ class GuardAuthenticatorHandlerTest extends TestCase
$this->sessionStrategy->expects($this->never()) $this->sessionStrategy->expects($this->never())
->method('onAuthentication'); ->method('onAuthentication');
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher, ['some_provider_key']); $handler = new GuardHandler($this->tokenStorage, $this->dispatcher, ['some_provider_key']);
$handler->setSessionAuthenticationStrategy($this->sessionStrategy); $handler->setSessionAuthenticationStrategy($this->sessionStrategy);
$handler->authenticateWithToken($this->token, $this->request, 'some_provider_key'); $handler->authenticateWithToken($this->token, $this->request, 'some_provider_key');
} }

View File

@ -18,7 +18,7 @@ use Symfony\Component\Security\Guard\AuthenticatorInterface;
use Symfony\Component\Security\Guard\Provider\GuardAuthenticationProvider; use Symfony\Component\Security\Guard\Provider\GuardAuthenticationProvider;
use Symfony\Component\Security\Guard\Token\GuardTokenInterface; use Symfony\Component\Security\Guard\Token\GuardTokenInterface;
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; use Symfony\Component\Security\Guard\Token\PreAuthenticationToken;
/** /**
* @author Ryan Weaver <weaverryan@gmail.com> * @author Ryan Weaver <weaverryan@gmail.com>
@ -143,11 +143,11 @@ class GuardAuthenticationProviderTest extends TestCase
$mockedUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(); $mockedUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, 'first_firewall', $this->userChecker); $provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, 'first_firewall', $this->userChecker);
$token = new PreAuthenticationGuardToken($mockedUser, 'first_firewall_1'); $token = new PreAuthenticationToken($mockedUser, 'first_firewall_1');
$supports = $provider->supports($token); $supports = $provider->supports($token);
$this->assertTrue($supports); $this->assertTrue($supports);
$token = new PreAuthenticationGuardToken($mockedUser, 'second_firewall_0'); $token = new PreAuthenticationToken($mockedUser, 'second_firewall_0');
$supports = $provider->supports($token); $supports = $provider->supports($token);
$this->assertFalse($supports); $this->assertFalse($supports);
} }
@ -162,7 +162,7 @@ class GuardAuthenticationProviderTest extends TestCase
$mockedUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(); $mockedUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, 'first_firewall', $this->userChecker); $provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, 'first_firewall', $this->userChecker);
$token = new PreAuthenticationGuardToken($mockedUser, 'second_firewall_0'); $token = new PreAuthenticationToken($mockedUser, 'second_firewall_0');
$provider->authenticate($token); $provider->authenticate($token);
} }
@ -170,7 +170,9 @@ class GuardAuthenticationProviderTest extends TestCase
{ {
$this->userProvider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock(); $this->userProvider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock();
$this->userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock(); $this->userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock();
$this->preAuthenticationToken = $this->getMockBuilder('Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken') $this->preAuthenticationToken = $this->getMockBuilder(
'Symfony\Component\Security\Guard\Token\PreAuthenticationToken'
)
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
} }

View File

@ -11,8 +11,6 @@
namespace Symfony\Component\Security\Guard\Token; namespace Symfony\Component\Security\Guard\Token;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticationGuardToken as CorePreAuthenticationGuardToken;
/** /**
* The token used by the guard auth system before authentication. * The token used by the guard auth system before authentication.
* *
@ -22,6 +20,10 @@ use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticationGuardT
* *
* @author Ryan Weaver <ryan@knpuniversity.com> * @author Ryan Weaver <ryan@knpuniversity.com>
*/ */
class PreAuthenticationGuardToken extends CorePreAuthenticationGuardToken implements GuardTokenInterface class PreAuthenticationToken extends \Symfony\Component\Security\Http\Authenticator\Token\CorePreAuthenticationGuardToken implements GuardTokenInterface
{ {
public function getGuardKey()
{
return $this->getAuthenticatorKey();
}
} }

View File

@ -13,7 +13,7 @@ namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authentication\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\AuthenticationException;
@ -25,7 +25,7 @@ use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterfa
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/** /**
* A utility class that does much of the *work* during the guard authentication process. * A utility class that does much of the *work* during the authentication process.
* *
* By having the logic here instead of the listener, more of the process * By having the logic here instead of the listener, more of the process
* can be called directly (e.g. for manual authentication) or overridden. * can be called directly (e.g. for manual authentication) or overridden.
@ -34,7 +34,7 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
* *
* @internal * @internal
*/ */
class GuardAuthenticatorHandler class AuthenticatorHandler
{ {
private $tokenStorage; private $tokenStorage;
private $dispatcher; private $dispatcher;
@ -66,24 +66,24 @@ class GuardAuthenticatorHandler
} }
/** /**
* Returns the "on success" response for the given GuardAuthenticator. * Returns the "on success" response for the given Authenticator.
* *
* @param AuthenticatorInterface|GuardAuthenticatorInterface $guardAuthenticator * @param AuthenticatorInterface|GuardAuthenticatorInterface $authenticator
*/ */
public function handleAuthenticationSuccess(TokenInterface $token, Request $request, $guardAuthenticator, string $providerKey): ?Response public function handleAuthenticationSuccess(TokenInterface $token, Request $request, $authenticator, string $providerKey): ?Response
{ {
if (!$guardAuthenticator instanceof AuthenticatorInterface && !$guardAuthenticator instanceof GuardAuthenticatorInterface) { if (!$authenticator instanceof AuthenticatorInterface && !$authenticator instanceof GuardAuthenticatorInterface) {
throw new \UnexpectedValueException('Invalid guard authenticator passed to '.__METHOD__.'. Expected AuthenticatorInterface of either Security Core or Security Guard.'); throw new \UnexpectedValueException('Invalid authenticator passed to '.__METHOD__.'. Expected AuthenticatorInterface of either Security Core or Security Guard.');
} }
$response = $guardAuthenticator->onAuthenticationSuccess($request, $token, $providerKey); $response = $authenticator->onAuthenticationSuccess($request, $token, $providerKey);
// check that it's a Response or null // check that it's a Response or null
if ($response instanceof Response || null === $response) { if ($response instanceof Response || null === $response) {
return $response; return $response;
} }
throw new \UnexpectedValueException(sprintf('The "%s::onAuthenticationSuccess()" method must return null or a Response object. You returned "%s".', \get_class($guardAuthenticator), get_debug_type($response))); throw new \UnexpectedValueException(sprintf('The "%s::onAuthenticationSuccess()" method must return null or a Response object. You returned "%s".', \get_class($authenticator), \is_object($response) ? \get_class($response) : \gettype($response)));
} }
/** /**
@ -95,7 +95,7 @@ class GuardAuthenticatorHandler
public function authenticateUserAndHandleSuccess(UserInterface $user, Request $request, $authenticator, string $providerKey): ?Response public function authenticateUserAndHandleSuccess(UserInterface $user, Request $request, $authenticator, string $providerKey): ?Response
{ {
if (!$authenticator instanceof AuthenticatorInterface && !$authenticator instanceof GuardAuthenticatorInterface) { if (!$authenticator instanceof AuthenticatorInterface && !$authenticator instanceof GuardAuthenticatorInterface) {
throw new \UnexpectedValueException('Invalid guard authenticator passed to '.__METHOD__.'. Expected AuthenticatorInterface of either Security Core or Security Guard.'); throw new \UnexpectedValueException('Invalid authenticator passed to '.__METHOD__.'. Expected AuthenticatorInterface of either Security Core or Security Guard.');
} }
// create an authenticated token for the User // create an authenticated token for the User
@ -111,21 +111,21 @@ class GuardAuthenticatorHandler
* Handles an authentication failure and returns the Response for the * Handles an authentication failure and returns the Response for the
* GuardAuthenticator. * GuardAuthenticator.
* *
* @param AuthenticatorInterface|GuardAuthenticatorInterface $guardAuthenticator * @param AuthenticatorInterface|GuardAuthenticatorInterface $authenticator
*/ */
public function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, $guardAuthenticator, string $providerKey): ?Response public function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, $authenticator, string $providerKey): ?Response
{ {
if (!$guardAuthenticator instanceof AuthenticatorInterface && !$guardAuthenticator instanceof GuardAuthenticatorInterface) { if (!$authenticator instanceof AuthenticatorInterface && !$authenticator instanceof GuardAuthenticatorInterface) {
throw new \UnexpectedValueException('Invalid guard authenticator passed to '.__METHOD__.'. Expected AuthenticatorInterface of either Security Core or Security Guard.'); throw new \UnexpectedValueException('Invalid authenticator passed to '.__METHOD__.'. Expected AuthenticatorInterface of either Security Core or Security Guard.');
} }
$response = $guardAuthenticator->onAuthenticationFailure($request, $authenticationException); $response = $authenticator->onAuthenticationFailure($request, $authenticationException);
if ($response instanceof Response || null === $response) { if ($response instanceof Response || null === $response) {
// returning null is ok, it means they want the request to continue // returning null is ok, it means they want the request to continue
return $response; return $response;
} }
throw new \UnexpectedValueException(sprintf('The "%s::onAuthenticationFailure()" method must return null or a Response object. You returned "%s".', \get_class($guardAuthenticator), get_debug_type($response))); throw new \UnexpectedValueException(sprintf('The "%s::onAuthenticationFailure()" method must return null or a Response object. You returned "%s".', \get_class($authenticator), get_debug_type($response)));
} }
/** /**

View File

@ -15,8 +15,8 @@ use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterfac
use Symfony\Component\Security\Core\Exception\BadCredentialsException; use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Authentication\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticationGuardToken; use Symfony\Component\Security\Http\Authenticator\Token\PreAuthenticationToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\AuthenticationEvents; use Symfony\Component\Security\Core\AuthenticationEvents;
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent; use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
@ -33,20 +33,20 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
* *
* @experimental in 5.1 * @experimental in 5.1
*/ */
class GuardAuthenticationManager implements AuthenticationManagerInterface class AuthenticatorManager implements AuthenticationManagerInterface
{ {
use GuardAuthenticationManagerTrait; use AuthenticatorManagerTrait;
private $guardAuthenticators; private $authenticators;
private $eventDispatcher; private $eventDispatcher;
private $eraseCredentials; private $eraseCredentials;
/** /**
* @param iterable|AuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationListener * @param AuthenticatorInterface[] $authenticators The authenticators, with keys that match what's passed to AuthenticatorManagerListener
*/ */
public function __construct(iterable $guardAuthenticators, EventDispatcherInterface $eventDispatcher, bool $eraseCredentials = true) public function __construct(iterable $authenticators, EventDispatcherInterface $eventDispatcher, bool $eraseCredentials = true)
{ {
$this->guardAuthenticators = $guardAuthenticators; $this->authenticators = $authenticators;
$this->eventDispatcher = $eventDispatcher; $this->eventDispatcher = $eventDispatcher;
$this->eraseCredentials = $eraseCredentials; $this->eraseCredentials = $eraseCredentials;
} }
@ -58,10 +58,10 @@ class GuardAuthenticationManager implements AuthenticationManagerInterface
public function authenticate(TokenInterface $token) public function authenticate(TokenInterface $token)
{ {
if (!$token instanceof PreAuthenticationGuardToken) { if (!$token instanceof PreAuthenticationToken) {
/* /*
* The listener *only* passes PreAuthenticationGuardToken instances. * The listener *only* passes PreAuthenticationToken instances.
* This means that an authenticated token (e.g. PostAuthenticationGuardToken) * This means that an authenticated token (e.g. PostAuthenticationToken)
* is being passed here, which happens if that token becomes * is being passed here, which happens if that token becomes
* "not authenticated" (e.g. happens if the user changes between * "not authenticated" (e.g. happens if the user changes between
* requests). In this case, the user should be logged out. * requests). In this case, the user should be logged out.
@ -77,13 +77,13 @@ class GuardAuthenticationManager implements AuthenticationManagerInterface
throw new AuthenticationExpiredException(); throw new AuthenticationExpiredException();
} }
$guard = $this->findOriginatingAuthenticator($token); $authenticator = $this->findOriginatingAuthenticator($token);
if (null === $guard) { if (null === $authenticator) {
$this->handleFailure(new ProviderNotFoundException(sprintf('Token with provider key "%s" did not originate from any of the guard authenticators.', $token->getGuardProviderKey())), $token); $this->handleFailure(new ProviderNotFoundException(sprintf('Token with provider key "%s" did not originate from any of the authenticators.', $token->getAuthenticatorKey())), $token);
} }
try { try {
$result = $this->authenticateViaGuard($guard, $token, $token->getProviderKey()); $result = $this->authenticateViaAuthenticator($authenticator, $token, $token->getProviderKey());
} catch (AuthenticationException $exception) { } catch (AuthenticationException $exception) {
$this->handleFailure($exception, $token); $this->handleFailure($exception, $token);
} }
@ -101,14 +101,14 @@ class GuardAuthenticationManager implements AuthenticationManagerInterface
return $result; return $result;
} }
protected function getGuardKey(string $key): string protected function getAuthenticatorKey(string $key): string
{ {
// Guard authenticators in the GuardAuthenticationManager are already indexed // Authenticators in the AuthenticatorManager are already indexed
// by an unique key // by an unique key
return $key; return $key;
} }
private function authenticateViaGuard(AuthenticatorInterface $authenticator, PreAuthenticationGuardToken $token, string $providerKey): TokenInterface private function authenticateViaAuthenticator(AuthenticatorInterface $authenticator, PreAuthenticationToken $token, string $providerKey): TokenInterface
{ {
// get the user from the Authenticator // get the user from the Authenticator
$user = $authenticator->getUser($token->getCredentials()); $user = $authenticator->getUser($token->getCredentials());

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\Security\Guard\AuthenticatorInterface as GuardAuthenticatorInterface;
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface as CoreAuthenticatorInterface;
use Symfony\Component\Security\Http\Authenticator\Token\PreAuthenticationToken;
/**
* @author Ryan Weaver <ryan@knpuniversity.com>
*
* @internal
*/
trait AuthenticatorManagerTrait
{
/**
* @return CoreAuthenticatorInterface|GuardAuthenticatorInterface|null
*/
private function findOriginatingAuthenticator(PreAuthenticationToken $token)
{
// find the *one* Authenticator that this token originated from
foreach ($this->authenticators as $key => $authenticator) {
// get a key that's unique to *this* authenticator
// this MUST be the same as AuthenticatorManagerListener
$uniqueAuthenticatorKey = $this->getAuthenticatorKey($key);
if ($uniqueAuthenticatorKey === $token->getAuthenticatorKey()) {
return $authenticator;
}
}
// no matching authenticator found
return null;
}
abstract protected function getAuthenticatorKey(string $key): string;
}

View File

@ -1,55 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\Security\Http\Authentication\Authenticator\AuthenticatorInterface as CoreAuthenticatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticationGuardToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\LogicException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Guard\AuthenticatorInterface;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
/**
* @author Ryan Weaver <ryan@knpuniversity.com>
*
* @internal
*/
trait GuardAuthenticationManagerTrait
{
/**
* @return CoreAuthenticatorInterface|\Symfony\Component\Security\Guard\AuthenticatorInterface|null
*/
private function findOriginatingAuthenticator(PreAuthenticationGuardToken $token)
{
// find the *one* GuardAuthenticator that this token originated from
foreach ($this->guardAuthenticators as $key => $guardAuthenticator) {
// get a key that's unique to *this* guard authenticator
// this MUST be the same as GuardAuthenticationListener
$uniqueGuardKey = $this->getGuardKey($key);
if ($uniqueGuardKey === $token->getGuardProviderKey()) {
return $guardAuthenticator;
}
}
// no matching authenticator found - but there will be multiple GuardAuthenticationProvider
// instances that will be checked if you have multiple firewalls.
return null;
}
abstract protected function getGuardKey(string $key): string;
}

View File

@ -9,11 +9,11 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Symfony\Component\Security\Http\Authentication\Authenticator; namespace Symfony\Component\Security\Http\Authenticator;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; use Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken;
/** /**
* An optional base class that creates the necessary tokens for you. * An optional base class that creates the necessary tokens for you.
@ -25,13 +25,13 @@ use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
abstract class AbstractAuthenticator implements AuthenticatorInterface abstract class AbstractAuthenticator implements AuthenticatorInterface
{ {
/** /**
* Shortcut to create a PostAuthenticationGuardToken for you, if you don't really * Shortcut to create a PostAuthenticationToken for you, if you don't really
* care about which authenticated token you're using. * care about which authenticated token you're using.
* *
* @return PostAuthenticationGuardToken * @return PostAuthenticationToken
*/ */
public function createAuthenticatedToken(UserInterface $user, string $providerKey): TokenInterface public function createAuthenticatedToken(UserInterface $user, string $providerKey): TokenInterface
{ {
return new PostAuthenticationGuardToken($user, $providerKey, $user->getRoles()); return new PostAuthenticationToken($user, $providerKey, $user->getRoles());
} }
} }

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Symfony\Component\Security\Http\Authentication\Authenticator; namespace Symfony\Component\Security\Http\Authenticator;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -25,7 +25,7 @@ use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface
* *
* @experimental in 5.1 * @experimental in 5.1
*/ */
abstract class AbstractFormLoginAuthenticator extends AbstractAuthenticator implements AuthenticationEntryPointInterface abstract class AbstractLoginFormAuthenticator extends AbstractAuthenticator implements AuthenticationEntryPointInterface
{ {
/** /**
* Return the URL to the login page. * Return the URL to the login page.

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Symfony\Component\Security\Http\Authentication\Authenticator; namespace Symfony\Component\Security\Http\Authenticator;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Symfony\Component\Security\Http\Authentication\Authenticator; namespace Symfony\Component\Security\Http\Authenticator;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;

View File

@ -1,6 +1,15 @@
<?php <?php
namespace Symfony\Component\Security\Http\Authentication\Authenticator; /*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Authenticator;
use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;

View File

@ -9,22 +9,18 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Symfony\Component\Security\Http\Authentication\Authenticator; namespace Symfony\Component\Security\Http\Authenticator;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException; use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\HttpUtils; use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\ParameterBagUtils; use Symfony\Component\Security\Http\ParameterBagUtils;
use Symfony\Component\Security\Http\Util\TargetPathTrait; use Symfony\Component\Security\Http\Util\TargetPathTrait;
@ -36,7 +32,7 @@ use Symfony\Component\Security\Http\Util\TargetPathTrait;
* @final * @final
* @experimental in 5.1 * @experimental in 5.1
*/ */
class FormLoginAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface class FormLoginAuthenticator extends AbstractLoginFormAuthenticator implements PasswordAuthenticatedInterface
{ {
use TargetPathTrait; use TargetPathTrait;

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Symfony\Component\Security\Http\Authentication\Authenticator; namespace Symfony\Component\Security\Http\Authenticator;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -20,7 +20,6 @@ use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
/** /**

View File

@ -0,0 +1,31 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Authenticator;
/**
* This interface should be implemented when the authenticator
* uses a password to authenticate.
*
* The EncoderFactory will be used to automatically validate
* the password.
*
* @author Wouter de Jong <wouter@wouterj.nl>
*/
interface PasswordAuthenticatedInterface
{
/**
* Returns the clear-text password contained in credentials if any.
*
* @param mixed $credentials The user credentials
*/
public function getPassword($credentials): ?string;
}

View File

@ -0,0 +1,71 @@
<?php
namespace Symfony\Component\Security\Http\Authenticator\Token;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\User\UserInterface;
class PostAuthenticationToken extends AbstractToken
{
private $providerKey;
/**
* @param string $providerKey The provider (firewall) key
* @param string[] $roles An array of roles
*
* @throws \InvalidArgumentException
*/
public function __construct(UserInterface $user, string $providerKey, array $roles)
{
parent::__construct($roles);
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey (i.e. firewall key) must not be empty.');
}
$this->setUser($user);
$this->providerKey = $providerKey;
// this token is meant to be used after authentication success, so it is always authenticated
// you could set it as non authenticated later if you need to
$this->setAuthenticated(true);
}
/**
* This is meant to be only an authenticated token, where credentials
* have already been used and are thus cleared.
*
* {@inheritdoc}
*/
public function getCredentials()
{
return [];
}
/**
* Returns the provider (firewall) key.
*
* @return string
*/
public function getProviderKey()
{
return $this->providerKey;
}
/**
* {@inheritdoc}
*/
public function __serialize(): array
{
return [$this->providerKey, parent::__serialize()];
}
/**
* {@inheritdoc}
*/
public function __unserialize(array $data): void
{
[$this->providerKey, $parentData] = $data;
parent::__unserialize($parentData);
}
}

View File

@ -9,32 +9,34 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Symfony\Component\Security\Core\Authentication\Token; namespace Symfony\Component\Security\Http\Authenticator\Token;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
/** /**
* The token used by the guard auth system before authentication. * The token used by the authenticator system before authentication.
* *
* The GuardAuthenticationListener creates this, which is then consumed * The AuthenticatorManagerListener creates this, which is then consumed
* immediately by the GuardAuthenticationProvider. If authentication is * immediately by the AuthenticatorManager. If authentication is
* successful, a different authenticated token is returned * successful, a different authenticated token is returned
* *
* @author Ryan Weaver <ryan@knpuniversity.com> * @author Ryan Weaver <ryan@knpuniversity.com>
*/ */
class PreAuthenticationGuardToken extends AbstractToken class PreAuthenticationToken extends AbstractToken
{ {
private $credentials; private $credentials;
private $guardProviderKey; private $authenticatorProviderKey;
private $providerKey; private $providerKey;
/** /**
* @param mixed $credentials * @param mixed $credentials
* @param string $guardProviderKey Unique key that bind this token to a specific AuthenticatorInterface * @param string $authenticatorProviderKey Unique key that bind this token to a specific AuthenticatorInterface
* @param string|null $providerKey The general provider key (when using with HTTP, this is the firewall name) * @param string|null $providerKey The general provider key (when using with HTTP, this is the firewall name)
*/ */
public function __construct($credentials, string $guardProviderKey, ?string $providerKey = null) public function __construct($credentials, string $authenticatorProviderKey, ?string $providerKey = null)
{ {
$this->credentials = $credentials; $this->credentials = $credentials;
$this->guardProviderKey = $guardProviderKey; $this->authenticatorProviderKey = $authenticatorProviderKey;
$this->providerKey = $providerKey; $this->providerKey = $providerKey;
parent::__construct([]); parent::__construct([]);
@ -48,9 +50,9 @@ class PreAuthenticationGuardToken extends AbstractToken
return $this->providerKey; return $this->providerKey;
} }
public function getGuardProviderKey() public function getAuthenticatorKey()
{ {
return $this->guardProviderKey; return $this->authenticatorProviderKey;
} }
/** /**
@ -66,6 +68,6 @@ class PreAuthenticationGuardToken extends AbstractToken
public function setAuthenticated(bool $authenticated) public function setAuthenticated(bool $authenticated)
{ {
throw new \LogicException('The PreAuthenticationGuardToken is *never* authenticated.'); throw new \LogicException('The PreAuthenticationToken is *never* authenticated.');
} }
} }

View File

@ -1,6 +1,15 @@
<?php <?php
namespace Symfony\Component\Security\Http\Authentication\Authenticator; /*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Authenticator;
/** /**
* This interface should be implemented when the authenticator * This interface should be implemented when the authenticator

View File

@ -5,7 +5,7 @@ namespace Symfony\Component\Security\Http\Event;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authentication\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Contracts\EventDispatcher\Event; use Symfony\Contracts\EventDispatcher\Event;
/** /**

View File

@ -5,7 +5,7 @@ namespace Symfony\Component\Security\Http\Event;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Contracts\EventDispatcher\Event; use Symfony\Contracts\EventDispatcher\Event;
/** /**

View File

@ -4,7 +4,7 @@ namespace Symfony\Component\Security\Http\Event;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Authentication\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Contracts\EventDispatcher\Event; use Symfony\Contracts\EventDispatcher\Event;
/** /**

View File

@ -5,9 +5,9 @@ namespace Symfony\Component\Security\Http\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Security\Core\Exception\LogicException; use Symfony\Component\Security\Core\Exception\LogicException;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface; use Symfony\Component\Security\Http\Authenticator\CustomAuthenticatedInterface;
use Symfony\Component\Security\Http\Authentication\Authenticator\CustomAuthenticatedInterface; use Symfony\Component\Security\Http\Authenticator\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\Authentication\Authenticator\TokenAuthenticatedInterface; use Symfony\Component\Security\Http\Authenticator\TokenAuthenticatedInterface;
use Symfony\Component\Security\Http\Event\VerifyAuthenticatorCredentialsEvent; use Symfony\Component\Security\Http\Event\VerifyAuthenticatorCredentialsEvent;
/** /**

View File

@ -6,7 +6,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface; use Symfony\Component\Security\Http\Authenticator\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\Event\VerifyAuthenticatorCredentialsEvent; use Symfony\Component\Security\Http\Event\VerifyAuthenticatorCredentialsEvent;
/** /**
@ -32,7 +32,7 @@ class PasswordMigratingListener implements EventSubscriberInterface
} }
$authenticator = $event->getAuthenticator(); $authenticator = $event->getAuthenticator();
if (!$authenticator instanceof PasswordAuthenticatedInterface) { if (!$authenticator instanceof PasswordAuthenticatedInterface || !$authenticator instanceof PasswordUpgraderInterface) {
return; return;
} }
@ -51,10 +51,6 @@ class PasswordMigratingListener implements EventSubscriberInterface
return; return;
} }
if (!$authenticator instanceof PasswordUpgraderInterface) {
return;
}
$authenticator->upgradePassword($user, $passwordEncoder->encodePassword($user, $password)); $authenticator->upgradePassword($user, $passwordEncoder->encodePassword($user, $password));
} }

View File

@ -4,7 +4,7 @@ namespace Symfony\Component\Security\Http\EventListener;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\Authentication\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Http\Event\LoginFailureEvent; use Symfony\Component\Security\Http\Event\LoginFailureEvent;
use Symfony\Component\Security\Http\Event\LoginSuccessEvent; use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;

View File

@ -13,15 +13,13 @@ namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authentication\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authentication\AuthenticatorHandler;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticationGuardToken; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; use Symfony\Component\Security\Http\Authenticator\Token\PreAuthenticationToken;
use Symfony\Component\Security\Http\Event\LoginFailureEvent; use Symfony\Component\Security\Http\Event\LoginFailureEvent;
use Symfony\Component\Security\Http\Event\LoginSuccessEvent; use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
@ -32,25 +30,25 @@ use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
* *
* @experimental in 5.1 * @experimental in 5.1
*/ */
class GuardManagerListener class AuthenticatorManagerListener
{ {
use GuardManagerListenerTrait; use AuthenticatorManagerListenerTrait;
private $authenticationManager; private $authenticationManager;
private $guardHandler; private $authenticatorHandler;
private $guardAuthenticators; private $authenticators;
protected $providerKey; protected $providerKey;
private $eventDispatcher; private $eventDispatcher;
protected $logger; protected $logger;
/** /**
* @param AuthenticatorInterface[] $guardAuthenticators * @param AuthenticatorInterface[] $authenticators
*/ */
public function __construct(AuthenticationManagerInterface $authenticationManager, GuardAuthenticatorHandler $guardHandler, iterable $guardAuthenticators, string $providerKey, EventDispatcherInterface $eventDispatcher, ?LoggerInterface $logger = null) public function __construct(AuthenticationManagerInterface $authenticationManager, AuthenticatorHandler $authenticatorHandler, iterable $authenticators, string $providerKey, EventDispatcherInterface $eventDispatcher, ?LoggerInterface $logger = null)
{ {
$this->authenticationManager = $authenticationManager; $this->authenticationManager = $authenticationManager;
$this->guardHandler = $guardHandler; $this->authenticatorHandler = $authenticatorHandler;
$this->guardAuthenticators = $guardAuthenticators; $this->authenticators = $authenticators;
$this->providerKey = $providerKey; $this->providerKey = $providerKey;
$this->logger = $logger; $this->logger = $logger;
$this->eventDispatcher = $eventDispatcher; $this->eventDispatcher = $eventDispatcher;
@ -59,12 +57,12 @@ class GuardManagerListener
public function __invoke(RequestEvent $requestEvent) public function __invoke(RequestEvent $requestEvent)
{ {
$request = $requestEvent->getRequest(); $request = $requestEvent->getRequest();
$guardAuthenticators = $this->getSupportingGuardAuthenticators($request); $authenticators = $this->getSupportingAuthenticators($request);
if (!$guardAuthenticators) { if (!$authenticators) {
return; return;
} }
$this->executeAuthenticators($guardAuthenticators, $requestEvent); $this->executeAuthenticators($authenticators, $requestEvent);
} }
/** /**
@ -72,12 +70,12 @@ class GuardManagerListener
*/ */
protected function executeAuthenticators(array $authenticators, RequestEvent $event): void protected function executeAuthenticators(array $authenticators, RequestEvent $event): void
{ {
foreach ($authenticators as $key => $guardAuthenticator) { foreach ($authenticators as $key => $authenticator) {
$this->executeAuthenticator($key, $guardAuthenticator, $event); $this->executeAuthenticator($key, $authenticator, $event);
if ($event->hasResponse()) { if ($event->hasResponse()) {
if (null !== $this->logger) { if (null !== $this->logger) {
$this->logger->debug('The "{authenticator}" authenticator set the response. Any later authenticator will not be called', ['authenticator' => \get_class($guardAuthenticator)]); $this->logger->debug('The "{authenticator}" authenticator set the response. Any later authenticator will not be called', ['authenticator' => \get_class($authenticator)]);
} }
break; break;
@ -101,7 +99,7 @@ class GuardManagerListener
} }
// create a token with the unique key, so that the provider knows which authenticator to use // create a token with the unique key, so that the provider knows which authenticator to use
$token = $this->createPreAuthenticatedToken($credentials, $uniqueAuthenticatorKey, $this->providerKey); $token = new PreAuthenticationToken($credentials, $uniqueAuthenticatorKey, $uniqueAuthenticatorKey);
if (null !== $this->logger) { if (null !== $this->logger) {
$this->logger->debug('Passing token information to the AuthenticatorManager', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($authenticator)]); $this->logger->debug('Passing token information to the AuthenticatorManager', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($authenticator)]);
@ -115,7 +113,7 @@ class GuardManagerListener
} }
// sets the token on the token storage, etc // sets the token on the token storage, etc
$this->guardHandler->authenticateWithToken($token, $request, $this->providerKey); $this->authenticatorHandler->authenticateWithToken($token, $request, $this->providerKey);
} catch (AuthenticationException $e) { } catch (AuthenticationException $e) {
// oh no! Authentication failed! // oh no! Authentication failed!
@ -123,7 +121,7 @@ class GuardManagerListener
$this->logger->info('Authenticator failed.', ['exception' => $e, 'authenticator' => \get_class($authenticator)]); $this->logger->info('Authenticator failed.', ['exception' => $e, 'authenticator' => \get_class($authenticator)]);
} }
$response = $this->guardHandler->handleAuthenticationFailure($e, $request, $authenticator, $this->providerKey); $response = $this->authenticatorHandler->handleAuthenticationFailure($e, $request, $authenticator, $this->providerKey);
if ($response instanceof Response) { if ($response instanceof Response) {
$event->setResponse($response); $event->setResponse($response);
@ -135,7 +133,7 @@ class GuardManagerListener
} }
// success! // success!
$response = $this->guardHandler->handleAuthenticationSuccess($token, $request, $authenticator, $this->providerKey); $response = $this->authenticatorHandler->handleAuthenticationSuccess($token, $request, $authenticator, $this->providerKey);
if ($response instanceof Response) { if ($response instanceof Response) {
if (null !== $this->logger) { if (null !== $this->logger) {
$this->logger->debug('Authenticator set success response.', ['response' => $response, 'authenticator' => \get_class($authenticator)]); $this->logger->debug('Authenticator set success response.', ['response' => $response, 'authenticator' => \get_class($authenticator)]);
@ -150,9 +148,4 @@ class GuardManagerListener
$this->eventDispatcher->dispatch(new LoginSuccessEvent($authenticator, $token, $request, $response, $this->providerKey)); $this->eventDispatcher->dispatch(new LoginSuccessEvent($authenticator, $token, $request, $response, $this->providerKey));
} }
protected function createPreAuthenticatedToken($credentials, string $uniqueAuthenticatorKey, string $providerKey): PreAuthenticationGuardToken
{
return new PreAuthenticationGuardToken($credentials, $uniqueAuthenticatorKey, $providerKey);
}
} }

View File

@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\HttpFoundation\Request;
/**
* @author Ryan Weaver <ryan@knpuniversity.com>
* @author Amaury Leroux de Lens <amaury@lerouxdelens.com>
*
* @internal
*/
trait AuthenticatorManagerListenerTrait
{
protected function getSupportingAuthenticators(Request $request): array
{
$authenticators = [];
foreach ($this->authenticators as $key => $authenticator) {
if (null !== $this->logger) {
$this->logger->debug('Checking support on authenticator.', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($authenticator)]);
}
if ($authenticator->supports($request)) {
$authenticators[$key] = $authenticator;
} elseif (null !== $this->logger) {
$this->logger->debug('Authenticator does not support the request.', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($authenticator)]);
}
}
return $authenticators;
}
}

View File

@ -1,50 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Http\Authentication\Authenticator\AuthenticatorInterface as CoreAuthenticatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticationGuardToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Guard\AuthenticatorInterface;
/**
* @author Ryan Weaver <ryan@knpuniversity.com>
* @author Amaury Leroux de Lens <amaury@lerouxdelens.com>
*
* @internal
*/
trait GuardManagerListenerTrait
{
protected function getSupportingGuardAuthenticators(Request $request): array
{
$guardAuthenticators = [];
foreach ($this->guardAuthenticators as $key => $guardAuthenticator) {
if (null !== $this->logger) {
$this->logger->debug('Checking support on guard authenticator.', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)]);
}
if ($guardAuthenticator->supports($request)) {
$guardAuthenticators[$key] = $guardAuthenticator;
} elseif (null !== $this->logger) {
$this->logger->debug('Guard authenticator does not support the request.', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)]);
}
}
return $guardAuthenticators;
}
abstract protected function createPreAuthenticatedToken($credentials, string $uniqueGuardKey, string $providerKey): PreAuthenticationGuardToken;
}