Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit afea80e

Browse filesBrowse files
Merge branch '5.4' into 6.0
* 5.4: [Security] make TokenInterface::getUser() nullable to tell about unauthenticated tokens [Messenger] fix compat with Serializer v6
2 parents dfccd79 + 695a83b commit afea80e
Copy full SHA for afea80e

File tree

15 files changed

+65
-36
lines changed
Filter options

15 files changed

+65
-36
lines changed

‎UPGRADE-5.4.md

Copy file name to clipboardExpand all lines: UPGRADE-5.4.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ Security
112112
behavior when using `enable_authenticator_manager: true`)
113113
* Deprecate not setting the `$exceptionOnNoToken` argument of `AccessListener` to `false`
114114
(this is the default behavior when using `enable_authenticator_manager: true`)
115-
* Deprecate `TokenInterface:isAuthenticated()` and `setAuthenticated()` methods without replacement.
116-
Security tokens won't have an "authenticated" flag anymore, so they will always be considered authenticated
115+
* Deprecate `TokenInterface:isAuthenticated()` and `setAuthenticated()` methods,
116+
return `null` from `getUser()` instead when a token is not authenticated
117117
* Deprecate `DeauthenticatedEvent`, use `TokenDeauthenticatedEvent` instead
118118
* Deprecate `CookieClearingLogoutHandler`, `SessionLogoutHandler` and `CsrfTokenClearingLogoutHandler`.
119119
Use `CookieClearingLogoutListener`, `SessionLogoutListener` and `CsrfTokenClearingLogoutListener` instead

‎UPGRADE-6.0.md

Copy file name to clipboardExpand all lines: UPGRADE-6.0.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,8 @@ Security
365365
`UsernamePasswordFormAuthenticationListener`, `UsernamePasswordJsonAuthenticationListener` and `X509AuthenticationListener`
366366
from security-http, use the new authenticator system instead
367367
* Remove the Guard component, use the new authenticator system instead
368-
* Remove `TokenInterface:isAuthenticated()` and `setAuthenticated()` methods without replacement.
369-
Security tokens won't have an "authenticated" flag anymore, so they will always be considered authenticated
368+
* Remove `TokenInterface:isAuthenticated()` and `setAuthenticated()`,
369+
return `null` from `getUser()` instead when a token is not authenticated
370370
* Remove `DeauthenticatedEvent`, use `TokenDeauthenticatedEvent` instead
371371
* Remove `CookieClearingLogoutHandler`, `SessionLogoutHandler` and `CsrfTokenClearingLogoutHandler`.
372372
Use `CookieClearingLogoutListener`, `SessionLogoutListener` and `CsrfTokenClearingLogoutListener` instead

‎src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function __invoke(array $record): array
4242

4343
if (null !== $token = $this->getToken()) {
4444
$record['extra'][$this->getKey()] = [
45-
'authenticated' => method_exists($token, 'isAuthenticated') ? $token->isAuthenticated(false) : true, // @deprecated since Symfony 5.4, always true in 6.0
45+
'authenticated' => method_exists($token, 'isAuthenticated') ? $token->isAuthenticated(false) : (bool) $token->getUser(),
4646
'roles' => $token->getRoleNames(),
4747
];
4848

‎src/Symfony/Bridge/Twig/AppVariable.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/AppVariable.php
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\HttpFoundation\Session\Session;
1717
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
1818
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
19+
use Symfony\Component\Security\Core\User\UserInterface;
1920

2021
/**
2122
* Exposes some Symfony parameters and services as an "app" global variable.
@@ -68,7 +69,7 @@ public function getToken(): ?TokenInterface
6869
*
6970
* @see TokenInterface::getUser()
7071
*/
71-
public function getUser(): ?object
72+
public function getUser(): ?UserInterface
7273
{
7374
if (null === $tokenStorage = $this->tokenStorage) {
7475
throw new \RuntimeException('The "app.user" variable is not available.');

‎src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public function collect(Request $request, Response $response, \Throwable $except
119119

120120
$this->data = [
121121
'enabled' => true,
122-
'authenticated' => method_exists($token, 'isAuthenticated') ? $token->isAuthenticated(false) : true,
122+
'authenticated' => method_exists($token, 'isAuthenticated') ? $token->isAuthenticated(false) : (bool) $token->getUser(),
123123
'impersonated' => null !== $impersonatorUser,
124124
'impersonator_user' => $impersonatorUser,
125125
'impersonation_exit_path' => null,

‎src/Symfony/Component/Messenger/Transport/Serialization/Normalizer/FlattenExceptionNormalizer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Transport/Serialization/Normalizer/FlattenExceptionNormalizer.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ final class FlattenExceptionNormalizer implements DenormalizerInterface, Context
2929
/**
3030
* {@inheritdoc}
3131
*/
32-
public function normalize(mixed $object, string $format = null, array $context = []): array|string|int|float|bool|\ArrayObject|null
32+
public function normalize(mixed $object, string $format = null, array $context = []): array
3333
{
3434
$normalized = [
3535
'message' => $object->getMessage(),
@@ -59,7 +59,7 @@ public function supportsNormalization(mixed $data, string $format = null, array
5959
/**
6060
* {@inheritdoc}
6161
*/
62-
public function denormalize(mixed $data, string $type, string $format = null, array $context = []): mixed
62+
public function denormalize(mixed $data, string $type, string $format = null, array $context = []): FlattenException
6363
{
6464
$object = new FlattenException();
6565

‎src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php
+3-12Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace Symfony\Component\Security\Core\Authentication;
1313

14-
use Symfony\Component\Security\Core\Authentication\Token\NullToken;
1514
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
1615
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1716

@@ -24,30 +23,22 @@ class AuthenticationTrustResolver implements AuthenticationTrustResolverInterfac
2423
{
2524
public function isAuthenticated(TokenInterface $token = null): bool
2625
{
27-
return null !== $token && !$token instanceof NullToken;
26+
return $token && $token->getUser();
2827
}
2928

3029
/**
3130
* {@inheritdoc}
3231
*/
3332
public function isRememberMe(TokenInterface $token = null)
3433
{
35-
if (null === $token) {
36-
return false;
37-
}
38-
39-
return $token instanceof RememberMeToken;
34+
return $token && $token instanceof RememberMeToken;
4035
}
4136

4237
/**
4338
* {@inheritdoc}
4439
*/
4540
public function isFullFledged(TokenInterface $token = null)
4641
{
47-
if (null === $token || $token instanceof NullToken) {
48-
return false;
49-
}
50-
51-
return !$this->isRememberMe($token);
42+
return $this->isAuthenticated($token) && !$this->isRememberMe($token);
5243
}
5344
}

‎src/Symfony/Component/Security/Core/Authentication/Token/NullToken.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Authentication/Token/NullToken.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function getRoleNames(): array
3030

3131
public function getUser()
3232
{
33-
return '';
33+
return null;
3434
}
3535

3636
public function setUser(UserInterface $user)

‎src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function getRoleNames(): array;
4040
/**
4141
* Returns a user representation.
4242
*
43-
* @return UserInterface
43+
* @return UserInterface|null
4444
*
4545
* @see AbstractToken::setUser()
4646
*/

‎src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php
+6-2Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class AuthorizationChecker implements AuthorizationCheckerInterface
3232

3333
public function __construct(TokenStorageInterface $tokenStorage, AccessDecisionManagerInterface $accessDecisionManager, bool $exceptionOnNoToken = false)
3434
{
35-
if (false !== $exceptionOnNoToken) {
35+
if ($exceptionOnNoToken) {
3636
throw new \LogicException('Argument $exceptionOnNoToken of "%s()" must be set to "false".', __METHOD__);
3737
}
3838

@@ -48,7 +48,11 @@ public function __construct(TokenStorageInterface $tokenStorage, AccessDecisionM
4848
*/
4949
final public function isGranted(mixed $attribute, mixed $subject = null): bool
5050
{
51-
$token = $this->tokenStorage->getToken() ?? new NullToken();
51+
$token = $this->tokenStorage->getToken();
52+
53+
if (!$token || !$token->getUser()) {
54+
$token = new NullToken();
55+
}
5256

5357
return $this->accessDecisionManager->decide($token, [$attribute], $subject);
5458
}

‎src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\Component\Security\Core\Authorization\Voter;
1313

1414
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
15-
use Symfony\Component\Security\Core\Authentication\Token\NullToken;
1615
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
1716
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1817

‎src/Symfony/Component/Security/Core/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/CHANGELOG.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ CHANGELOG
2525
* Deprecate setting the `$alwaysAuthenticate` argument to `true` and not setting the
2626
`$exceptionOnNoToken` argument to `false` of `AuthorizationChecker`
2727
* Deprecate methods `TokenInterface::isAuthenticated()` and `setAuthenticated`,
28-
tokens will always be considered authenticated in 6.0
28+
return null from "getUser()" instead when a token is not authenticated
2929

3030
5.3
3131
---

‎src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php
+18-4Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public function testIsRememberMe()
2525
$resolver = new AuthenticationTrustResolver();
2626

2727
$this->assertFalse($resolver->isRememberMe(null));
28-
$this->assertFalse($resolver->isRememberMe($this->getToken()));
2928
$this->assertFalse($resolver->isRememberMe(new FakeCustomToken()));
3029
$this->assertTrue($resolver->isRememberMe(new RealCustomRememberMeToken()));
3130
$this->assertTrue($resolver->isRememberMe($this->getRememberMeToken()));
@@ -38,7 +37,6 @@ public function testisFullFledged()
3837
$this->assertFalse($resolver->isFullFledged(null));
3938
$this->assertFalse($resolver->isFullFledged($this->getRememberMeToken()));
4039
$this->assertFalse($resolver->isFullFledged(new RealCustomRememberMeToken()));
41-
$this->assertTrue($resolver->isFullFledged($this->getToken()));
4240
$this->assertTrue($resolver->isFullFledged(new FakeCustomToken()));
4341
}
4442

@@ -50,9 +48,24 @@ public function testIsAuthenticated()
5048
$this->assertTrue($resolver->isAuthenticated(new FakeCustomToken()));
5149
}
5250

53-
protected function getToken()
51+
public function testIsRememberMeWithClassAsConstructorButStillExtending()
5452
{
55-
return $this->createMock(TokenInterface::class);
53+
$resolver = new AuthenticationTrustResolver();
54+
55+
$this->assertFalse($resolver->isRememberMe(null));
56+
$this->assertFalse($resolver->isRememberMe(new FakeCustomToken()));
57+
$this->assertTrue($resolver->isRememberMe($this->getRememberMeToken()));
58+
$this->assertTrue($resolver->isRememberMe(new RealCustomRememberMeToken()));
59+
}
60+
61+
public function testisFullFledgedWithClassAsConstructorButStillExtending()
62+
{
63+
$resolver = new AuthenticationTrustResolver();
64+
65+
$this->assertFalse($resolver->isFullFledged(null));
66+
$this->assertFalse($resolver->isFullFledged($this->getRememberMeToken()));
67+
$this->assertFalse($resolver->isFullFledged(new RealCustomRememberMeToken()));
68+
$this->assertTrue($resolver->isFullFledged(new FakeCustomToken()));
5669
}
5770

5871
protected function getRememberMeToken()
@@ -95,6 +108,7 @@ public function getCredentials(): mixed
95108

96109
public function getUser(): UserInterface
97110
{
111+
return new InMemoryUser('wouter', '', ['ROLE_USER']);
98112
}
99113

100114
public function setUser($user)

‎src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php
+22-5Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver;
16+
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
17+
use Symfony\Component\Security\Core\Authentication\Token\NullToken;
1618
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
1719
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
18-
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1920
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
2021
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
22+
use Symfony\Component\Security\Core\User\InMemoryUser;
2123

2224
class AuthenticatedVoterTest extends TestCase
2325
{
@@ -53,12 +55,27 @@ public function getVoteTests()
5355

5456
protected function getToken($authenticated)
5557
{
58+
$user = new InMemoryUser('wouter', '', ['ROLE_USER']);
59+
5660
if ('fully' === $authenticated) {
57-
return $this->createMock(TokenInterface::class);
58-
} elseif ('remembered' === $authenticated) {
59-
return $this->getMockBuilder(RememberMeToken::class)->setMethods(['setPersistent'])->disableOriginalConstructor()->getMock();
60-
} elseif ('impersonated' === $authenticated) {
61+
$token = new class() extends AbstractToken {
62+
public function getCredentials()
63+
{
64+
}
65+
};
66+
$token->setUser($user);
67+
68+
return $token;
69+
}
70+
71+
if ('remembered' === $authenticated) {
72+
return new RememberMeToken($user, 'foo', 'bar');
73+
}
74+
75+
if ('impersonated' === $authenticated) {
6176
return $this->getMockBuilder(SwitchUserToken::class)->disableOriginalConstructor()->getMock();
6277
}
78+
79+
return new NullToken();
6380
}
6481
}

‎src/Symfony/Component/Security/Http/EventListener/UserCheckerListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/EventListener/UserCheckerListener.php
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public function preCheckCredentials(CheckPassportEvent $event): void
4545
public function postCheckCredentials(AuthenticationSuccessEvent $event): void
4646
{
4747
$user = $event->getAuthenticationToken()->getUser();
48+
if (!$user instanceof UserInterface) {
49+
return;
50+
}
4851

4952
$this->userChecker->checkPostAuth($user);
5053
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.