Skip to content

[Security] Allow RememberMeHandler to use a custom RememberMeDetails class #44459

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

Open
wants to merge 7 commits into
base: 7.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
[Security] [RememberMe] Allow RememberMeHandlers to use custom Rememb…
…erMeDetails implementation
  • Loading branch information
Patrick Elshof committed Jun 6, 2022
commit ce7b8d469b6af79219d2b1ae2d17c40cf2e4c191
8 changes: 8 additions & 0 deletions src/Symfony/Bundle/SecurityBundle/RememberMe/DecoratedRememberMeHandler.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): U
return $this->handler->consumeRememberMeCookie($rememberMeDetails);
}

/**
* {@inheritDoc}
*/
public function getUserIdentifierForCookie(RememberMeDetails $rememberMeDetails): string
{
return $this->handler->getUserIdentifierForCookie($rememberMeDetails);
}

/**
* {@inheritDoc}
*/
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Bundle/SecurityBundle/RememberMe/FirewallAwareRememberMeHandler.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,9 @@ public function clearRememberMeCookie(): void
{
$this->getForFirewall()->clearRememberMeCookie();
}

public function getUserIdentifierForCookie(RememberMeDetails $rememberMeDetails): string
{
return $this->getForFirewall()->getUserIdentifierForCookie($rememberMeDetails);
}
}
17 changes: 15 additions & 2 deletions src/Symfony/Component/Security/Http/Authenticator/RememberMeAuthenticator.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Wouter de Jong <wouter@wouterj.nl>
* @author Patrick Elshof <tyrelcher@protonmail.com>
*
* @final
*/
Expand Down Expand Up @@ -86,9 +87,21 @@ public function authenticate(Request $request): Passport
throw new \LogicException('No remember-me cookie is found.');
}

$rememberMeCookie = RememberMeDetails::fromRawCookie($rawCookie);
if (!is_callable([$this->rememberMeHandler, 'getRememberMeDetails'])) {
trigger_deprecation('symfony/security-http', '6.1', 'RememberMeHandlers should implement method "getRememberMeDetails()".');
$rememberMeCookie = RememberMeDetails::fromRawCookie($rawCookie);
} else {
$rememberMeCookie = $this->rememberMeHandler->getRememberMeDetails($rawCookie);
}

if (!is_callable([$this->rememberMeHandler, 'getUserIdentifierForCookie'])) {
trigger_deprecation('symfony/security-http', '6.1', 'RememberMeHandlers should implement method "getUserIdentifierForCookie()".');
$userIdentifier = $rememberMeCookie->getUserIdentifier();
} else {
$userIdentifier = $this->rememberMeHandler->getUserIdentifierForCookie($rememberMeCookie);
}

return new SelfValidatingPassport(new UserBadge($rememberMeCookie->getUserIdentifier(), function () use ($rememberMeCookie) {
return new SelfValidatingPassport(new UserBadge($userIdentifier, function () use ($rememberMeCookie) {
return $this->rememberMeHandler->consumeRememberMeCookie($rememberMeCookie);
}));
}
Expand Down
30 changes: 27 additions & 3 deletions src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeHandler.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@

/**
* @author Wouter de Jong <wouter@wouterj.nl>
* @author Patrick Elshof <tyrelcher@protonmail.com>
*/
abstract class AbstractRememberMeHandler implements RememberMeHandlerInterface
{
private UserProviderInterface $userProvider;
protected $requestStack;
protected $options;
protected $logger;
protected RequestStack $requestStack;
protected array $options;
protected ?LoggerInterface $logger;

public function __construct(UserProviderInterface $userProvider, RequestStack $requestStack, array $options = [], LoggerInterface $logger = null)
{
Expand Down Expand Up @@ -89,6 +90,29 @@ public function clearRememberMeCookie(): void
$this->createCookie(null);
}

/**
* Retrieves the User Identifier for the RememberMe cookie.
*
* If the cookie is required to contain the User Identifier {@see UserInterface::getUserIdentifier()}
* then it can simply be retrieved from the provided cookie details; if not, then it could be retrieved
* from elsewhere based on some other information provided (e.g. in a database).
*/
public function getUserIdentifierForCookie(RememberMeDetails $rememberMeDetails): string
{
return $rememberMeDetails->getUserIdentifier();
}

/**
* Retrieves the RememberMeDetails using the raw cookie.
*
* This method allows the authenticator to retrieve the cookie details without needing
* to care about the implementation details used by the RememberMeHandler.
*/
public function getRememberMeDetails(string $rawCookie): RememberMeDetails
{
return RememberMeDetails::fromRawCookie($rawCookie);
}

/**
* Creates the remember-me cookie using the correct configuration.
*
Expand Down
22 changes: 22 additions & 0 deletions src/Symfony/Component/Security/Http/RememberMe/RememberMeHandlerInterface.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* {@see AbstractRememberMeHandler} instead.
*
* @author Wouter de Jong <wouter@wouterj.nl>
* @author Patrick Elshof <tyrelcher@protonmail.com>
*/
interface RememberMeHandlerInterface
{
Expand Down Expand Up @@ -51,4 +52,25 @@ public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): U
* This should set a cookie with a `null` value on the request attribute.
*/
public function clearRememberMeCookie(): void;

/**
* Retrieves the User Identifier for the RememberMe cookie.
*
* If the cookie is required to contain the User Identifier {@see UserInterface::getUserIdentifier()}
* then it can simply be retrieved from the provided cookie details; if not, then it could be retrieved
* from elsewhere based on some other information provided (e.g. in a database).
*
* Cannot be added to 6.1 because of backwards compatibility.
*/
//public function getUserIdentifierForCookie(RememberMeDetails $rememberMeDetails): string;

/**
* Retrieves the RememberMeDetails using the raw cookie.
*
* This method allows the authenticator to retrieve the cookie details without needing
* to care about the implementation details of the RememberMeDetails used by the RememberMeHandler.
*
* Cannot be added to 6.1 because of backwards compatibility.
*/
//public function getRememberMeDetails(string $rawCookie): RememberMeDetails;
}