// get the user to be authenticated
$user = ...;
// log the user in on the current firewall
$security->login($user);
// if the firewall has more than one authenticator, you must pass it explicitly
// by using the name of built-in authenticators...
$security->login($user, 'form_login');
// ...or the service id of custom authenticators
$security->login($user, ExampleAuthenticator::class);
// you can also log in on a different firewall...
$security->login($user, 'form_login', 'other_firewall');
// ...and add badges
$security->login($user, 'form_login', 'other_firewall', [(new RememberMeBadge())->enable()]);
// use the redirection logic applied to regular login
$redirectResponse = $security->login($user);
return $redirectResponse;
<?php
namespace App\Security;
use Psr\Log\LoggerInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Security\Core\User\InMemoryUser;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\AccessToken\AccessTokenHandlerInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
class AccessTokenHandler implements AccessTokenHandlerInterface
{
final public const TOKEN_NAME = 'api_token';
public function __construct(
private UserProviderInterface $userProvider,
private UserPasswordHasherInterface $passwordHasher,
private LoggerInterface $logger,
) {
}
public function getUserBadgeFrom(?string $accessToken): UserBadge
{
if (null === $accessToken || !$this->verifyCredentials($accessToken)) {
throw new BadCredentialsException('Invalid credentials.');
}
return new UserBadge(self::TOKEN_NAME);
}
private function verifyCredentials(string $accessToken): bool
{
$user = $this->userProvider->loadUserByIdentifier(self::TOKEN_NAME);
if (get_class($user) !== InMemoryUser::class) {
$userClass = get_class($user);
$requiredUserClass = InMemoryUser::class;
$this->logger->error("Invalid User Class for access token authentication. Got $userClass but require $requiredUserClass");
return false;
}
return $this->passwordHasher->isPasswordValid($user, $accessToken);
}
}
version.html.twig
...
{% if is_granted('ROLE_API') %}
{# tried both this and the below code leads to the same #}
{% endif %}
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
App Version: {{ app_version }}
{% endif %}
...
cest
public function VersionIsVisibleForApiUsersCest(FunctionalTester $I): void
{
$user = new InMemoryUser(AccessTokenHandler::TOKEN_NAME, '<my dummy password>', ['ROLES_API']);
$I->amOnPage('/');
$I->amLoggedInAs($user, 'main');
$I->amOnPage('/version');
$I->see('App Version');
}
so the old code to autologin doesn't work any more or does not work with the acces token handler. the code from above fails silently, the user is simply not logged in (as far as i can verify).
switching to a custom code which uses the new security helper and its locin helper
cest:
symfony changed their security again. the code to do the automated login looks like that:
https://symfony.com/doc/7.0/security.html#login-programmatically
having the following config:
security.yaml
src/Security/AccessTokenHandler.php
version.html.twig
cest
so the old code to autologin doesn't work any more or does not work with the acces token handler. the code from above fails silently, the user is simply not logged in (as far as i can verify).
switching to a custom code which uses the new security helper and its locin helper
cest
:services.yaml
:leads to
i wanted to try to set the header for this request but only found https://github.com/Codeception/Codeception/issues/5308
any thoughts?