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 b7c55c8

Browse filesBrowse files
[Security] Unset token roles when serializing it and user implements EquatableInterface
1 parent 5cab1e1 commit b7c55c8
Copy full SHA for b7c55c8

File tree

3 files changed

+25
-10
lines changed
Filter options

3 files changed

+25
-10
lines changed

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

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

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

14+
use Symfony\Component\Security\Core\User\EquatableInterface;
1415
use Symfony\Component\Security\Core\User\InMemoryUser;
1516
use Symfony\Component\Security\Core\User\UserInterface;
1617

@@ -23,24 +24,24 @@
2324
abstract class AbstractToken implements TokenInterface, \Serializable
2425
{
2526
private ?UserInterface $user = null;
26-
private array $roleNames = [];
27+
private array $roleNames;
2728
private array $attributes = [];
2829

2930
/**
3031
* @param string[] $roles An array of roles
31-
*
32-
* @throws \InvalidArgumentException
3332
*/
3433
public function __construct(array $roles = [])
3534
{
35+
$this->roleNames = [];
36+
3637
foreach ($roles as $role) {
37-
$this->roleNames[] = $role;
38+
$this->roleNames[] = (string) $role;
3839
}
3940
}
4041

4142
public function getRoleNames(): array
4243
{
43-
return $this->roleNames;
44+
return $this->roleNames ??= self::__construct($this->user->getRoles()) ?? $this->roleNames;
4445
}
4546

4647
public function getUserIdentifier(): string
@@ -82,7 +83,13 @@ public function eraseCredentials(): void
8283
*/
8384
public function __serialize(): array
8485
{
85-
return [$this->user, true, null, $this->attributes, $this->roleNames];
86+
$data = [$this->user, true, null, $this->attributes];
87+
88+
if (!$this->user instanceof EquatableInterface) {
89+
$data[] = $this->roleNames;
90+
}
91+
92+
return $data;
8693
}
8794

8895
/**
@@ -103,7 +110,12 @@ public function __serialize(): array
103110
*/
104111
public function __unserialize(array $data): void
105112
{
106-
[$user, , , $this->attributes, $this->roleNames] = $data;
113+
[$user, , , $this->attributes] = $data;
114+
115+
if (\array_key_exists(4, $data)) {
116+
$this->roleNames = $data[4];
117+
}
118+
107119
$this->user = \is_string($user) ? new InMemoryUser($user, '', $this->roleNames, false) : $user;
108120
}
109121

‎src/Symfony/Component/Security/Core/Tests/Exception/CustomUserMessageAuthenticationExceptionTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Core/Tests/Exception/CustomUserMessageAuthenticationExceptionTest.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public function testSharedSerializedData()
5353
$exception->setSafeMessage('message', ['token' => $token]);
5454

5555
$processed = unserialize(serialize($exception));
56+
$this->assertSame($token->getRoleNames(), $processed->getToken()->getRoleNames());
5657
$this->assertEquals($token, $processed->getToken());
5758
$this->assertEquals($token, $processed->getMessageData()['token']);
5859
$this->assertSame($processed->getToken(), $processed->getMessageData()['token']);
@@ -67,6 +68,7 @@ public function testSharedSerializedDataFromChild()
6768
$exception->setToken($token);
6869

6970
$processed = unserialize(serialize($exception));
71+
$this->assertSame($token->getRoleNames(), $processed->getToken()->getRoleNames());
7072
$this->assertEquals($token, $processed->childMember);
7173
$this->assertEquals($token, $processed->getToken());
7274
$this->assertSame($processed->getToken(), $processed->childMember);

‎src/Symfony/Component/Security/Http/Firewall/ContextListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Firewall/ContextListener.php
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,12 @@ private static function hasUserChanged(UserInterface $originalUser, TokenInterfa
301301
}
302302
}
303303

304-
$userRoles = array_map('strval', $refreshedUser->getRoles());
304+
$refreshedRoles = array_map('strval', $refreshedUser->getRoles());
305+
$originalRoles = $refreshedToken->getRoleNames(); // This comes from cloning the original token, so it still contains the roles of the original user
305306

306307
if (
307-
\count($userRoles) !== \count($refreshedToken->getRoleNames())
308-
|| \count($userRoles) !== \count(array_intersect($userRoles, $refreshedToken->getRoleNames()))
308+
\count($refreshedRoles) !== \count($originalRoles)
309+
|| \count($refreshedRoles) !== \count(array_intersect($refreshedRoles, $originalRoles))
309310
) {
310311
return true;
311312
}

0 commit comments

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