To configurate that is on the the official website and also on this tutorial in SymfonyCast, but basically you can authenticate the user as you want:
See the next example:
Create a file on src\App\Security folder if your configuration is using the default config and create the class TokenAuthenticator, now see the below code, in this case check the class App\Service\ExternalAuthenticator, who will be in charge to get the information from other service or api and the return.
<?php
namespace App\Security;
use App\Example\Student;
use App\Service\ExternalAuthenticator;
use App\DTO\INFORMATIONFROMOTHERSERVICE;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Security;
final class TokenAuthenticator extends AbstractGuardAuthenticator
{
/** @var Security */
private $security;
/** @var ExternalAuthenticator */
private $externalAuthenticator;
/** @var UrlGeneratorInterface */
private $urlGenerator;
public function __construct(
Security $security,
ExternalAuthenticator $externalAuthenticator
) {
$this->security = $security;
$this->externalAuthenticator = $externalAuthenticator;
}
/**
* {@inheritDoc}
*/
public function supports(Request $request)
{
//on this example, this guard must be using if on the request contains the word token
$response = false;
$apiKey = $request->query->get('token');
if (!is_null($apiKey)) {
$response = true;
}
return $response;
}
/**
* {@inheritDoc}
*/
public function getCredentials(Request $request)
{
$apiKey = $request->query->get('token');
// Validate with anything you want, other service or api
/** @var INFORMATIONFROMOTHERSERVICE**/
$dtoToken = $this->externalAuthenticator->validateToken($apiKey, $simulator);
return $dtoToken;
}
/**
* @param INFORMATIONFROMOTHERSERVICE $credentials
* @param UserProviderInterface $userProvider
* @return INFORMATIONFROMOTHERSERVICE |UserInterface|null
*/
public function getUser($credentials, UserProviderInterface $userProvider)
{
return $userProvider;
}
public function checkCredentials($credentials, UserInterface $user)
{
return true;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
return new RedirectResponse($this->urlGenerator->generate('home_incorrect'));
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
{
return new RedirectResponse($request->getPathInfo());
}
public function start(Request $request, AuthenticationException $authException = null)
{
return new RedirectResponse($this->urlGenerator->generate('home_incorrect'));
}
public function supportsRememberMe()
{
// todo
}
}
Now the external service must return App\DTO\INFORMATIONFROMOTHERSERVICE class, but this class must implement the UserInterface, now with this in mind. We need to configurate what guard must be in charge of what routes, see the next example:
security:
encoders:
App\Entity\User:
algorithm: bcrypt
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
//You can use a
custom_provider:
id : App\DTO\INFORMATIONFROMOTHERSERVICE
# used to reload user from session & other features (e.g. switch_user)
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
survey:
anonymous: true
pattern: ^/(custom_path)/
// The
provider: custom_provider
guard:
// You can use as many authenticator that you want, but in the node entrypoint, you must choose who must be the default if only is one you could remove the entrypoint node, similar as the main firewall
authenticators:
- App\Security\TokenAuthenticator
- App\Security\OtherAuthenticator
entry_point: App\Security\OtherAuthenticator
main:
anonymous: true
lazy: true
provider: app_user_provider
logout:
path: app_logout
guard:
authenticators:
- App\Security\AppAuthenticator
Also see the next documentation, that will guide you to create the class App\DTO\INFORMATIONFROMOTHERSERVICE.
I hope this answer, help you