8000 [Security] Deprecate `TokenInterface::isAuthenticated()` by chalasr · Pull Request #42050 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Security] Deprecate TokenInterface::isAuthenticated() #42050

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions UPGRADE-5.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ Security
behavior when using `enable_authenticator_manager: true`)
* Deprecate not setting the 5th argument (`$exceptionOnNoToken`) of `AccessListener` to `false`
(this is the default behavior when using `enable_authenticator_manager: true`)
* Deprecate `TokenInterface:isAuthenticated()` and `setAuthenticated()` methods without replacement.
Security tokens won't have an "authenticated" flag anymore, so they will always be considered authenticated
* Deprecate `DeauthenticatedEvent`, use `TokenDeauthenticatedEvent` instead
3 changes: 3 additions & 0 deletions UPGRADE-6.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,9 @@ Security
`UsernamePasswordFormAuthenticationListener`, `UsernamePasswordJsonAuthenticationListener` and `X509AuthenticationListener`
from security-http, use the new authenticator system instead
* Remove the Guard component, use the new authenticator system instead
* Remove `TokenInterface:isAuthenticated()` and `setAuthenticated()` methods without replacement.
Security tokens won't have an "authenticated" flag anymore, so they will always be considered authenticated
* Remove `DeauthenticatedEvent`, use `TokenDeauthenticatedEvent` instead

SecurityBundle
--------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function __invoke(array $record): array

if (null !== $token = $this->getToken()) {
$record['extra'][$this->getKey()] = [
'authenticated' => $token->isAuthenticated(),
'authenticated' => $token->isAuthenticated(false), // @deprecated since Symfony 5.4, always true in 6.0
'roles' => $token->getRoleNames(),
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public function testLegacyProcessor()

$this->assertArrayHasKey('token', $record['extra']);
$this->assertEquals($token->getUsername(), $record['extra']['token']['username']);
$this->assertEquals($token->isAuthenticated(), $record['extra']['token']['authenticated']);
$this->assertEquals(['ROLE_USER'], $record['extra']['token']['roles']);
}

Expand All @@ -59,7 +58,6 @@ public function testProcessor()

$this->assertArrayHasKey('token', $record['extra']);
$this->assertEquals($token->getUserIdentifier(), $record['extra']['token']['user_identifier']);
$this->assertEquals($token->isAuthenticated(), $record['extra']['token']['authenticated']);
$this->assertEquals(['ROLE_USER'], $record['extra']['token']['roles']);
}
}
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public function loginUser(object $user, string $firewallContext = 'main'): self
}

$token = new TestBrowserToken($user->getRoles(), $user, $firewallContext);
$token->setAuthenticated(true);
$token->setAuthenticated(true, false);

$container = $this->getContainer();
$container->get('security.untracked_token_storage')->setToken($token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public function collect(Request $request, Response $response, \Throwable $except

$this->data = [
'enabled' => true,
'authenticated' => $token->isAuthenticated(),
'authenticated' => $token->isAuthenticated(false),
'impersonated' => null !== $impersonatorUser,
'impersonator_user' => $impersonatorUser,
'impersonation_exit_path' => null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,12 @@ public function setUser($user)
throw new \InvalidArgumentException('$user must be an instanceof UserInterface, an object implementing a __toString method, or a primitive string.');
}

if (null === $this->user) {
// @deprecated since Symfony 5.4, remove the whole block if/elseif/else block in 6.0
if (1 < \func_num_args() && !func_get_arg(1)) {
// ContextListener checks if the user has changed on its own and calls `setAuthenticated()` subsequently,
// avoid doing the same checks twice
$changed = false;
} elseif (null === $this->user) {
$changed = false;
} elseif ($this->user instanceof UserInterface) {
if (!$user instanceof UserInterface) {
Expand All @@ -113,18 +118,25 @@ public function setUser($user)
$changed = (string) $this->user !== (string) $user;
}

// @deprecated since Symfony 5.4
if ($changed) {
$this->setAuthenticated(false);
$this->setAuthenticated(false, false);
}

$this->user = $user;
}

/**
* {@inheritdoc}
*
* @deprecated since Symfony 5.4
*/
public function isAuthenticated()
{
if (1 > \func_num_args() || func_get_arg(0)) {
trigger_deprecation('symfony/security-core', '5.4', 'Method "%s()" is deprecated. In version 6.0, security tokens won\'t have an "authenticated" flag anymore and will always be considered authenticated.', __METHOD__);
}

return $this->authenticated;
}

Expand All @@ -133,6 +145,10 @@ public function isAuthenticated()
*/
public function setAuthenticated(bool $authenticated)
{
if (2 > \func_num_args() || func_get_arg(1)) {
trigger_deprecation('symfony/security-core', '5.4', 'Method "%s()" is deprecated. In version 6.0, security tokens won\'t have an "authenticated" state anymore and will always be considered as authenticated.', __METHOD__);
}

$this->authenticated = $authenticated;
}

Expand Down Expand Up @@ -275,6 +291,9 @@ final public function unserialize($serialized)
$this->__unserialize(\is_array($serialized) ? $serialized : unserialize($serialized));
}

/**
* @deprecated since Symfony 5.4
*/
private function hasUserChanged(UserInterface $user): bool
{
if (!($this->user instanceof UserInterface)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public function __construct(string $secret, $user, array $roles = [])

$this->secret = $secret;
$this->setUser($user);
$this->setAuthenticated(true);
// @deprecated since Symfony 5.4
$this->setAuthenticated(true, false);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,21 @@ public function getUserIdentifier(): string
return '';
}

/**
* @deprecated since Symfony 5.4
*/
public function isAuthenticated()
{
if (0 === \func_num_args() || func_get_arg(0)) {
trigger_deprecation('symfony/security-core', '5.4', 'Method "%s()" is deprecated. In version 6.0, security tokens won\'t have an "authenticated" flag anymore and will always be considered authenticated.', __METHOD__);
}

return true;
}

/**
* @deprecated since Symfony 5.4
*/
public function setAuthenticated(bool $isAuthenticated)
{
throw new \BadMethodCallException('Cannot change authentication state of NullToken.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function __construct($user, $credentials, string $firewallName, array $ro
$this->firewallName = $firewallName;

if ($roles) {
$this->setAuthenticated(true);
$this->setAuthenticated(true, false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function __construct(UserInterface $user, string $firewallName, string $s
$this->secret = $secret;

$this->setUser($user);
parent::setAuthenticated(true);
parent::setAuthenticated(true, false);
}

/**
Expand All @@ -56,7 +56,7 @@ public function setAuthenticated(bool $authenticated)
throw new \LogicException('You cannot set this token to authenticated after creation.');
}

parent::setAuthenticated(false);
parent::setAuthenticated(false, false);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,15 @@ public function setUser($user);
* Returns whether the user is authenticated or not.
*
* @return bool true if the token has been authenticated, false otherwise
*
* @deprecated since Symfony 5.4. In 6.0, security tokens will always be considered authenticated
*/
public function isAuthenticated();

/**
* Sets the authenticated flag.
*
* @deprecated since Symfony 5.4. In 6.0, security tokens will always be considered authenticated
*/
public function setAuthenticated(bool $isAuthenticated);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function __construct($user, $credentials, string $firewallName, array $ro
$this->credentials = $credentials;
$this->firewallName = $firewallName;

parent::setAuthenticated(\count($roles) > 0);
parent::setAuthenticated(\count($roles) > 0, false);
}

/**
Expand All @@ -54,7 +54,7 @@ public function setAuthenticated(bool $isAuthenticated)
throw new \LogicException('Cannot set this token to trusted after instantiation.');
}

parent::setAuthenticated(false);
parent::setAuthenticated(false, false);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ final public function isGranted($attribute, $subject = null): bool

$token = new NullToken();
} else {
if ($this->alwaysAuthenticate || !$token->isAuthenticated()) {
$authenticated = true;
// @deprecated since Symfony 5.4
if ($this->alwaysAuthenticate || !$authenticated = $token->isAuthenticated(false)) {
if (!($authenticated ?? true)) {
trigger_deprecation('symfony/core', '5.4', 'Returning false from "%s()" is deprecated and won\'t have any effect in Symfony 6.0 as security tokens will always be considered authenticated.');
}
$this->tokenStorage->setToken($token = $this->authenticationManager->authenticate($token));
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/Security/Core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ CHANGELOG

* Deprecate setting the 4th argument (`$alwaysAuthenticate`) to `true` and not setting the
5th argument (`$exceptionOnNoToken`) to `false` of `AuthorizationChecker`
* Deprecate methods `TokenInterface::isAuthenticated()` and `setAuthenticated`,
tokens will always be considered authenticated in 6.0

5.3
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function getUsername()

public function getRoles()
{
return [];
}

public function getPassword()
Expand Down Expand Up @@ -104,6 +105,9 @@ public function testConstructor()
$this->assertEquals(['ROLE_FOO'], $token->getRoleNames());
}

/**
* @group legacy
*/
public function testAuthenticatedFlag()
{
$token = new ConcreteToken();
Expand Down Expand Up @@ -158,6 +162,7 @@ public function getUsers()
}

/**
* @group legacy
* @dataProvider getUserChanges
*/
public function testSetUserSetsAuthenticatedToFalseWhenUserChanges($firstUser, $secondUser)
Expand Down Expand Up @@ -190,6 +195,7 @@ public function getUserChanges()
}

/**
* @group legacy
* @dataProvider getUsers
*/
public function testSetUserDoesNotSetAuthenticatedToFalseWhenUserDoesNotChange($user)
Expand All @@ -205,6 +211,9 @@ public function testSetUserDoesNotSetAuthenticatedToFalseWhenUserDoesNotChange($
$this->assertTrue($token->isAuthenticated());
}

/**
* @group legacy
*/
public function testIsUserChangedWhenSerializing()
{
$token = new ConcreteToken(['ROLE_ADMIN']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ class AnonymousTokenTest extends TestCase
{
public function testConstructor()
{
$token = new AnonymousToken('foo', 'bar');
$this->assertTrue($token->isAuthenticated());

$token = new AnonymousToken('foo', 'bar', ['ROLE_FOO']);
$this->assertEquals(['ROLE_FOO'], $token->getRoleNames());
}

/**
* @group legacy
*/
public function testIsAuthenticated()
{
$token = new AnonymousToken('foo', 'bar');
$this->assertTrue($token->isAuthenticated());
}

public function testGetKey()
{
$token = new AnonymousToken('foo', 'bar');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ class PreAuthenticatedTokenTest extends TestCase
{
public function testConstructor()
{
$token = new PreAuthenticatedToken('foo', 'bar', 'key');
$this->assertFalse($token->isAuthenticated());

$token = new PreAuthenticatedToken('foo', 'bar', 'key', ['ROLE_FOO']);
$this->assertTrue($token->isAuthenticated());
$this->assertEquals(['ROLE_FOO'], $token->getRoleNames());
$this->assertEquals('key', $token->getFirewallName());
}
Expand All @@ -45,4 +41,13 @@ public function testEraseCredentials()
$token->eraseCredentials();
$this->assertEquals('', $token->getCredentials());
}

/**
* @group legacy
*/
public function testIsAuthenticated()
{
$token = new PreAuthenticatedToken('foo', 'bar', 'key');
$this->assertFalse($token->isAuthenticated());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ public function testConstructor()
$this->assertEquals('foo', $token->getSecret());
$this->assertEquals(['ROLE_FOO'], $token->getRoleNames());
$this->assertSame($user, $token->getUser());
}

/**
* @group legacy
*/
public function testIsAuthenticated()
{
$user = $this->getUser();
$token = new RememberMeToken($user, 'fookey', 'foo');
$this->assertTrue($token->isAuthenticated());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Tests\Authentication\Token\Fixtures\CustomUser;
use Symfony\Component\Security\Core\User\InMemoryUser;
use Symfony\Component\Security\Core\User\UserInterface;

class SwitchUserTokenTest extends TestCase
Expand Down Expand Up @@ -42,6 +43,9 @@ public function testSerialize()
$this->assertEquals(['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'], $unserializedOriginalToken->getRoleNames());
}

/**
* @group legacy
*/
public function testSetUserDoesNotDeauthenticate()
{
$impersonated = new class() implements UserInterface {
Expand Down Expand Up @@ -75,7 +79,7 @@ public function getSalt()
}
};

$originalToken = new UsernamePasswordToken('impersonator', 'foo', 'provider-key', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']);
$originalToken = new UsernamePasswordToken(new InMemoryUser('impersonator', '', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']), 'foo', 'provider-key', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']);
$token = new SwitchUserToken($impersonated, 'bar', 'provider-key', ['ROLE_USER', 'ROLE_PREVIOUS_ADMIN'], $originalToken);
$token->setUser($impersonated);
$this->assertTrue($token->isAuthenticated());
Expand Down
Loading
0