Token was deauthenticated after trying to refresh it
As of Symfony 4.0, logout_on_user_change
is set to true
. That means a user will be logged out if it has been changed.
You should implement Symfony\Component\Security\Core\User\EquatableInterface
and add the isEqualTo
method:
class User implements EquatableInterface
{
public function isEqualTo(UserInterface $user)
{
if ($this->password !== $user->getPassword()) {
return false;
}
if ($this->salt !== $user->getSalt()) {
return false;
}
if ($this->username !== $user->getUsername()) {
return false;
}
return true;
}
}
Changelog
https://github.com/symfony/security-bundle/blob/master/CHANGELOG.md
4.1.0
The
logout_on_user_change
firewall option is deprecated and will be removed in 5.0.4.0.0
the firewall option
logout_on_user_change
is now always true, which will trigger a logout if the user changes between requests3.4.0
Added
logout_on_user_change
to the firewall options. This config item will trigger a logout when the user has changed. Should be set to true to avoid deprecations in the configuration.
The option wasn't documented by the time of writing this answer: https://github.com/symfony/symfony-docs/issues/8428, but it now is: https://symfony.com/doc/4.4/reference/configuration/security.html#logout-on-user-change
Side note on updating to a new major release
If you want to upgrade to a new major version, always update to the latest minor version first. That means update to 2.8 before updating to 3.0 and updating to 3.4 before going to 4.0. See Symfony 4: Compose your Applications by Fabien Potencier.
Symfony 3.0 = Symfony 2.8 - deprecated features
(..)
Symfony 4.0 = Symfony 3.4 - deprecated features + a new way to develop applications
Updating to a new major release is much easier if you're already on the latest minor release, because you can see all deprecation notices.
I haved the problem du to the getRoles function. My user didn't have any roles
When the token is contruct in UsernamePasswordToken , the token is not authenticated if there is empty roles :
class UsernamePasswordToken extends AbstractToken
{
..
public function __construct($user, $credentials, string $providerKey, array $roles = [])
{
parent::__construct($roles);
...
parent::setAuthenticated(\count($roles) > 0);
}
In other word, when user have empty roles, he is not authenticated.
I solved my problem by coding getRoles in my user class like the current doc https://symfony.com/doc/current/security.html#roles to guarantee every user at least has ROLE_USER
public function getRoles()
{
$roles = $this->roles;
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
Hope that help.