Add provider key in PreAuthenticationGuardToken

This is required to create the correct authenticated token in the
GuardAuthenticationManager.
This commit is contained in:
Wouter de Jong 2020-01-26 15:37:32 +01:00
parent 526f75608b
commit 50132587a1
7 changed files with 40 additions and 23 deletions

View File

@ -269,19 +269,6 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
if ($this->guardAuthenticationManagerEnabled) {
$authenticationManagerId = 'security.authentication.manager.guard';
$container->setAlias('security.authentication.manager', new Alias($authenticationManagerId));
// guard authentication manager listener
$container
->setDefinition('security.firewall.guard.'.$name.'locator', new ChildDefinition('security.firewall.guard.locator'))
->setArguments([$authenticationProviders])
->addTag('container.service_locator')
;
$container
->setDefinition('security.firewall.guard.'.$name, new ChildDefinition('security.firewall.guard'))
->replaceArgument(2, new Reference('security.firewall.guard.'.$name.'locator'))
->replaceArgument(3, $name)
->addTag('kernel.event_listener', ['event' => KernelEvents::REQUEST])
;
}
$container
->getDefinition($authenticationManagerId)
@ -431,7 +418,29 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
$configuredEntryPoint = isset($firewall['entry_point']) ? $firewall['entry_point'] : null;
// Authentication listeners
list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $authenticationProviders, $defaultProvider, $providerIds, $configuredEntryPoint, $contextListenerId);
$firewallAuthenticationProviders = [];
list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $firewallAuthenticationProviders, $defaultProvider, $providerIds, $configuredEntryPoint, $contextListenerId);
$authenticationProviders = array_merge($authenticationProviders, $firewallAuthenticationProviders);
if ($this->guardAuthenticationManagerEnabled) {
// guard authentication manager listener
$container
->setDefinition('security.firewall.guard.'.$id.'.locator', new ChildDefinition('security.firewall.guard.locator'))
->setArguments([array_map(function ($id) {
return new Reference($id);
}, $firewallAuthenticationProviders)])
->addTag('container.service_locator')
;
$container
->setDefinition('security.firewall.guard.'.$id, new ChildDefinition('security.firewall.guard'))
->replaceArgument(2, new Reference('security.firewall.guard.'.$id.'.locator'))
->replaceArgument(3, $id)
->addTag('kernel.event_listener', ['event' => KernelEvents::REQUEST])
;
$listeners[] = new Reference('security.firewall.guard.'.$id);
}
$config->replaceArgument(7, $configuredEntryPoint ?: $defaultEntryPoint);

View File

@ -81,7 +81,7 @@ class GuardAuthenticationManager implements AuthenticationManagerInterface
}
try {
$result = $this->authenticateViaGuard($guard, $token);
$result = $this->authenticateViaGuard($guard, $token, $token->getProviderKey());
} catch (AuthenticationException $exception) {
$this->handleFailure($exception, $token);
}

View File

@ -72,7 +72,7 @@ trait GuardAuthenticatorListenerTrait
}
// create a token with the unique key, so that the provider knows which authenticator to use
$token = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey);
$token = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey, $this->providerKey);
if (null !== $this->logger) {
$this->logger->debug('Passing guard token information to the GuardAuthenticationProvider', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)]);

View File

@ -93,7 +93,7 @@ class GuardAuthenticationProvider implements AuthenticationProviderInterface
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));
}
return $this->authenticateViaGuard($guardAuthenticator, $token);
return $this->authenticateViaGuard($guardAuthenticator, $token, $this->providerKey);
}
public function supports(TokenInterface $token)

View File

@ -28,7 +28,7 @@ use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken;
*/
trait GuardAuthenticationProviderTrait
{
private function authenticateViaGuard(AuthenticatorInterface $guardAuthenticator, PreAuthenticationGuardToken $token): GuardTokenInterface
private function authenticateViaGuard(AuthenticatorInterface $guardAuthenticator, PreAuthenticationGuardToken $token, string $providerKey): TokenInterface
{
// get the user from the GuardAuthenticator
$user = $guardAuthenticator->getUser($token->getCredentials(), $this->userProvider);
@ -55,7 +55,7 @@ trait GuardAuthenticationProviderTrait
$this->userChecker->checkPostAuth($user);
// turn the UserInterface into a TokenInterface
$authenticatedToken = $guardAuthenticator->createAuthenticatedToken($user, $this->providerKey);
$authenticatedToken = $guardAuthenticator->createAuthenticatedToken($user, $providerKey);
if (!$authenticatedToken instanceof TokenInterface) {
throw new \UnexpectedValueException(sprintf('The "%s::createAuthenticatedToken()" method must return a TokenInterface. You returned "%s".', get_debug_type($guardAuthenticator), get_debug_type($authenticatedToken)));
}

View File

@ -26,15 +26,18 @@ class PreAuthenticationGuardToken extends AbstractToken implements GuardTokenInt
{
private $credentials;
private $guardProviderKey;
private $providerKey;
/**
* @param mixed $credentials
* @param string $guardProviderKey Unique key that bind this token to a specific AuthenticatorInterface
* @param mixed $credentials
* @param string $guardProviderKey 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)
*/
public function __construct($credentials, string $guardProviderKey)
public function __construct($credentials, string $guardProviderKey, ?string $providerKey = null)
{
$this->credentials = $credentials;
$this->guardProviderKey = $guardProviderKey;
$this->providerKey = $providerKey;
parent::__construct([]);
@ -42,6 +45,11 @@ class PreAuthenticationGuardToken extends AbstractToken implements GuardTokenInt
parent::setAuthenticated(false);
}
public function getProviderKey(): ?string
{
return $this->providerKey;
}
public function getGuardProviderKey()
{
return $this->guardProviderKey;

View File

@ -57,7 +57,7 @@ class GuardManagerListener
protected function getGuardKey(string $key): string
{
// Guard authenticators in the GuardAuthenticationManager are already indexed
// Guard authenticators in the GuardManagerListener are already indexed
// by an unique key
return $key;
}