Skip to content

Commit a827842

Browse files
committed
remove the user FQCN from remember me cookies
1 parent b8b5059 commit a827842

File tree

7 files changed

+24
-87
lines changed

7 files changed

+24
-87
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
8.0
55
---
66

7+
* Remove `RememberMeDetails::getUserFqcn()`
78
* Remove callable firewall listeners support, extend `AbstractListener` or implement `FirewallListenerInterface` instead
89
* Remove `AbstractListener::__invoke`
910
* Throw a `BadCredentialsException` when passing an empty string as `$userIdentifier` argument to `UserBadge` constructor

RememberMe/PersistentRememberMeHandler.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,9 @@ public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): U
9393
}
9494

9595
return parent::consumeRememberMeCookie(new RememberMeDetails(
96-
method_exists($token, 'getClass') ? $token->getClass(false) : '',
9796
$token->getUserIdentifier(),
9897
$expires,
9998
$token->getLastUsed()->getTimestamp().':'.$series.':'.$tokenValue.':'.(method_exists($token, 'getClass') ? $token->getClass(false) : ''),
100-
false
10199
));
102100
}
103101

RememberMe/RememberMeDetails.php

Lines changed: 6 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -21,56 +21,11 @@ class RememberMeDetails
2121
{
2222
public const COOKIE_DELIMITER = ':';
2323

24-
private ?string $userFqcn = null;
25-
private string $userIdentifier;
26-
private int $expires;
27-
private string $value;
28-
29-
/**
30-
* @param string $userIdentifier
31-
* @param int $expires
32-
* @param string $value
33-
*/
3424
public function __construct(
35-
$userIdentifier,
36-
$expires,
37-
$value,
25+
private string $userIdentifier,
26+
private int $expires,
27+
private string $value,
3828
) {
39-
if (\func_num_args() > 3) {
40-
if (\func_num_args() < 5 || func_get_arg(4)) {
41-
trigger_deprecation('symfony/security-http', '7.4', 'Passing a user FQCN to %s() is deprecated. The user class will be removed from the remember-me cookie in 8.0.', __CLASS__, __NAMESPACE__);
42-
}
43-
44-
if (!\is_string($userIdentifier)) {
45-
throw new \TypeError(\sprintf('Argument 1 passed to "%s()" must be a string, "%s" given.', __METHOD__, get_debug_type($userIdentifier)));
46-
}
47-
48-
$this->userFqcn = $userIdentifier;
49-
$userIdentifier = $expires;
50-
$expires = $value;
51-
52-
if (\func_num_args() <= 3) {
53-
throw new \TypeError(\sprintf('Argument 4 passed to "%s()" must be a string, the argument is missing.', __METHOD__));
54-
}
55-
56-
$value = func_get_arg(3);
57-
}
58-
59-
if (!\is_string($userIdentifier)) {
60-
throw new \TypeError(\sprintf('The $userIdentifier argument passed to "%s()" must be a string, "%s" given.', __METHOD__, get_debug_type($userIdentifier)));
61-
}
62-
63-
if (!\is_int($expires) && !preg_match('/^\d+$/', $expires)) {
64-
throw new \TypeError(\sprintf('$The $expires argument passed to "%s()" must be an integer, "%s" given.', __METHOD__, get_debug_type($expires)));
65-
}
66-
67-
if (!\is_string($value)) {
68-
throw new \TypeError(\sprintf('The $value argument passed to "%s()" must be a string, "%s" given.', __METHOD__, get_debug_type($value)));
69-
}
70-
71-
$this->userIdentifier = $userIdentifier;
72-
$this->expires = $expires;
73-
$this->value = $value;
7429
}
7530

7631
public static function fromRawCookie(string $rawCookie): self
@@ -89,19 +44,14 @@ public static function fromRawCookie(string $rawCookie): self
8944
throw new AuthenticationException('The user identifier contains a character from outside the base64 alphabet.');
9045
}
9146

92-
if ('' === $cookieParts[0]) {
93-
unset($cookieParts[0]);
94-
} else {
95-
$cookieParts[0] = strtr($cookieParts[0], '.', '\\');
96-
$cookieParts[4] = false;
97-
}
47+
unset($cookieParts[0]);
9848

9949
return new static(...$cookieParts);
10050
}
10151

10252
public static function fromPersistentToken(PersistentToken $token, int $expires): self
10353
{
104-
return new static(method_exists($token, 'getClass') ? $token->getClass(false) : '', $token->getUserIdentifier(), $expires, $token->getSeries().':'.$token->getTokenValue(), false);
54+
return new static($token->getUserIdentifier(), $expires, $token->getSeries().':'.$token->getTokenValue());
10555
}
10656

10757
public function withValue(string $value): self
@@ -112,16 +62,6 @@ public function withValue(string $value): self
11262
return $details;
11363
}
11464

115-
/**
116-
* @deprecated since Symfony 7.4, the user FQCN will be removed from the remember-me cookie in 8.0
117-
*/
118-
public function getUserFqcn(): string
119-
{
120-
trigger_deprecation('symfony/security-http', '7.4', 'The "%s()" method is deprecated: the user FQCN will be removed from the remember-me cookie in 8.0.', __METHOD__);
121-
122-
return $this->userFqcn ?? '';
123-
}
124-
12565
public function getUserIdentifier(): string
12666
{
12767
return $this->userIdentifier;
@@ -140,6 +80,6 @@ public function getValue(): string
14080
public function toString(): string
14181
{
14282
// $userIdentifier is encoded because it might contain COOKIE_DELIMITER, we assume other values don't
143-
return implode(self::COOKIE_DELIMITER, [strtr($this->userFqcn ?? '', '\\', '.'), strtr(base64_encode($this->userIdentifier), '+/=', '-_~'), $this->expires, $this->value]);
83+
return implode(self::COOKIE_DELIMITER, ['', strtr(base64_encode($this->userIdentifier), '+/=', '-_~'), $this->expires, $this->value]);
14484
}
14585
}

RememberMe/SignatureRememberMeHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function createRememberMeCookie(UserInterface $user): void
4747
$expires = time() + $this->options['lifetime'];
4848
$value = $this->signatureHasher->computeSignatureHash($user, $expires);
4949

50-
$details = new RememberMeDetails($user::class, $user->getUserIdentifier(), $expires, $value, false);
50+
$details = new RememberMeDetails($user->getUserIdentifier(), $expires, $value);
5151
$this->createCookie($details);
5252
}
5353

Tests/Authenticator/RememberMeAuthenticatorTest.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ public static function provideSupportsData()
6969
public function testAuthenticate()
7070
{
7171
$rememberMeDetails = new RememberMeDetails('wouter', 1, 'secret');
72-
$cookieData = explode(RememberMeDetails::COOKIE_DELIMITER, $rememberMeDetails->toString());
73-
$cookieData[0] = '';
74-
$request = Request::create('/', 'GET', [], ['_remember_me_cookie' => implode(RememberMeDetails::COOKIE_DELIMITER, $cookieData)]);
72+
$request = Request::create('/', 'GET', [], ['_remember_me_cookie' => $rememberMeDetails->toString()]);
7573
$passport = $this->authenticator->authenticate($request);
7674

7775
$this->rememberMeHandler->expects($this->once())->method('consumeRememberMeCookie')->with($this->callback(fn ($arg) => $rememberMeDetails == $arg));
@@ -80,7 +78,7 @@ public function testAuthenticate()
8078

8179
public function testAuthenticateLegacyCookieFormat()
8280
{
83-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 1, 'secret', false);
81+
$rememberMeDetails = new RememberMeDetails('wouter', 1, 'secret');
8482
$request = Request::create('/', 'GET', [], ['_remember_me_cookie' => $rememberMeDetails->toString()]);
8583
$passport = $this->authenticator->authenticate($request);
8684

Tests/RememberMe/PersistentRememberMeHandlerTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function testClearRememberMeCookie()
6161
->method('deleteTokenBySeries')
6262
->with('series1');
6363

64-
$this->request->cookies->set('REMEMBERME', (new RememberMeDetails(InMemoryUser::class, 'wouter', 0, 'series1:tokenvalue', false))->toString());
64+
$this->request->cookies->set('REMEMBERME', (new RememberMeDetails('wouter', 0, 'series1:tokenvalue'))->toString());
6565

6666
$this->handler->clearRememberMeCookie();
6767

@@ -104,7 +104,7 @@ public function testConsumeRememberMeCookieValid()
104104

105105
$this->tokenProvider->expects($this->once())->method('updateToken')->with('series1');
106106

107-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue', false);
107+
$rememberMeDetails = new RememberMeDetails('wouter', 360, 'series1:tokenvalue');
108108
$this->handler->consumeRememberMeCookie($rememberMeDetails);
109109

110110
// assert that the cookie has been updated with a new base64 encoded token value
@@ -136,7 +136,7 @@ public function testConsumeRememberMeCookieInvalidOwner()
136136
->willReturn($persistentToken)
137137
;
138138

139-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'jeremy', 360, 'series1:tokenvalue', false);
139+
$rememberMeDetails = new RememberMeDetails('jeremy', 360, 'series1:tokenvalue');
140140

141141
$this->expectException(AuthenticationException::class);
142142
$this->expectExceptionMessage('The cookie\'s hash is invalid.');
@@ -157,7 +157,7 @@ public function testConsumeRememberMeCookieInvalidValue()
157157
->willReturn($persistentToken)
158158
;
159159

160-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue:somethingelse', false);
160+
$rememberMeDetails = new RememberMeDetails('wouter', 360, 'series1:tokenvalue:somethingelse');
161161

162162
$this->expectException(AuthenticationException::class);
163163
$this->expectExceptionMessage('This token was already used. The account is possibly compromised.');
@@ -187,7 +187,7 @@ public function testConsumeRememberMeCookieValidByValidatorWithoutUpdate()
187187
->willReturn(true)
188188
;
189189

190-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:oldTokenValue', false);
190+
$rememberMeDetails = new RememberMeDetails('wouter', 360, 'series1:oldTokenValue');
191191
$handler->consumeRememberMeCookie($rememberMeDetails);
192192

193193
$this->assertFalse($this->request->attributes->has(ResponseListener::COOKIE_ATTR_NAME));
@@ -210,7 +210,7 @@ public function testConsumeRememberMeCookieInvalidToken()
210210

211211
$this->expectException(CookieTheftException::class);
212212

213-
$this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue', false));
213+
$this->handler->consumeRememberMeCookie(new RememberMeDetails('wouter', 360, 'series1:tokenvalue'));
214214
}
215215

216216
public function testConsumeRememberMeCookieExpired()
@@ -231,7 +231,7 @@ public function testConsumeRememberMeCookieExpired()
231231
$this->expectException(AuthenticationException::class);
232232
$this->expectExceptionMessage('The cookie has expired.');
233233

234-
$this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue', false));
234+
$this->handler->consumeRememberMeCookie(new RememberMeDetails('wouter', 360, 'series1:tokenvalue'));
235235
}
236236

237237
public function testBase64EncodedTokens()
@@ -250,7 +250,7 @@ public function testBase64EncodedTokens()
250250

251251
$this->tokenProvider->expects($this->once())->method('updateToken')->with('series1');
252252

253-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue', false);
253+
$rememberMeDetails = new RememberMeDetails('wouter', 360, 'series1:tokenvalue');
254254
$cookieData = explode(RememberMeDetails::COOKIE_DELIMITER, $rememberMeDetails->toString());
255255
$cookieData[0] = '';
256256
$rememberMeDetails = RememberMeDetails::fromRawCookie(base64_encode(implode(RememberMeDetails::COOKIE_DELIMITER, $cookieData)));
@@ -273,7 +273,7 @@ public function testBase64EncodedTokensLegacyFormat()
273273

274274
$this->tokenProvider->expects($this->once())->method('updateToken')->with('series1');
275275

276-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue', false);
276+
$rememberMeDetails = new RememberMeDetails('wouter', 360, 'series1:tokenvalue');
277277
$rememberMeDetails = RememberMeDetails::fromRawCookie(base64_encode($rememberMeDetails->toString()));
278278
$this->handler->consumeRememberMeCookie($rememberMeDetails);
279279
}

Tests/RememberMe/SignatureRememberMeHandlerTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public function testCreateRememberMeCookie()
5656

5757
/** @var Cookie $cookie */
5858
$cookie = $this->request->attributes->get(ResponseListener::COOKIE_ATTR_NAME);
59-
$this->assertEquals(strtr(InMemoryUser::class, '\\', '.').':d291dGVy:'.$expire.':'.$signature, $cookie->getValue());
59+
$this->assertEquals(':d291dGVy:'.$expire.':'.$signature, $cookie->getValue());
6060
}
6161

6262
public function testClearRememberMeCookie()
@@ -76,21 +76,21 @@ public function testConsumeRememberMeCookieValid()
7676
$signature = $this->signatureHasher->computeSignatureHash($user, $expire = time() + 3600);
7777
$this->userProvider->createUser(new InMemoryUser('wouter', null));
7878

79-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', $expire, $signature, false);
79+
$rememberMeDetails = new RememberMeDetails('wouter', $expire, $signature);
8080
$this->handler->consumeRememberMeCookie($rememberMeDetails);
8181

8282
$this->assertTrue($this->request->attributes->has(ResponseListener::COOKIE_ATTR_NAME));
8383

8484
/** @var Cookie $cookie */
8585
$cookie = $this->request->attributes->get(ResponseListener::COOKIE_ATTR_NAME);
86-
$this->assertNotEquals((new RememberMeDetails(InMemoryUser::class, 'wouter', $expire, $signature, false))->toString(), $cookie->getValue());
86+
$this->assertNotEquals((new RememberMeDetails('wouter', $expire, $signature))->toString(), $cookie->getValue());
8787
}
8888

8989
public function testConsumeRememberMeCookieInvalidHash()
9090
{
9191
$this->expectException(AuthenticationException::class);
9292
$this->expectExceptionMessage('The cookie\'s hash is invalid.');
93-
$this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', time() + 600, 'badsignature', false));
93+
$this->handler->consumeRememberMeCookie(new RememberMeDetails('wouter', time() + 600, 'badsignature'));
9494
}
9595

9696
public function testConsumeRememberMeCookieExpired()
@@ -100,6 +100,6 @@ public function testConsumeRememberMeCookieExpired()
100100

101101
$this->expectException(AuthenticationException::class);
102102
$this->expectExceptionMessage('The cookie has expired.');
103-
$this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', 360, $signature, false));
103+
$this->handler->consumeRememberMeCookie(new RememberMeDetails('wouter', 360, $signature));
104104
}
105105
}

0 commit comments

Comments
 (0)