RememberMeAuthenticator.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Security\Http\Authenticator;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpFoundation\Response;
  13. use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
  14. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  15. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  16. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  17. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  18. use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
  19. use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
  20. use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
  21. /**
  22. * The RememberMe *Authenticator* performs remember me authentication.
  23. *
  24. * This authenticator is executed whenever a user's session
  25. * expired and a remember me cookie was found. This authenticator
  26. * then "re-authenticates" the user using the information in the
  27. * cookie.
  28. *
  29. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  30. * @author Wouter de Jong <wouter@wouterj.nl>
  31. *
  32. * @final
  33. */
  34. class RememberMeAuthenticator implements InteractiveAuthenticatorInterface
  35. {
  36. private $rememberMeServices;
  37. private $secret;
  38. private $tokenStorage;
  39. private $options = [];
  40. public function __construct(RememberMeServicesInterface $rememberMeServices, string $secret, TokenStorageInterface $tokenStorage, array $options)
  41. {
  42. $this->rememberMeServices = $rememberMeServices;
  43. $this->secret = $secret;
  44. $this->tokenStorage = $tokenStorage;
  45. $this->options = $options;
  46. }
  47. public function supports(Request $request): ?bool
  48. {
  49. // do not overwrite already stored tokens (i.e. from the session)
  50. if (null !== $this->tokenStorage->getToken()) {
  51. return false;
  52. }
  53. // if the attribute is set, this is a lazy firewall. The previous
  54. // support call already indicated support, so return null and avoid
  55. // recreating the cookie
  56. if ($request->attributes->has('_remember_me_token')) {
  57. return null;
  58. }
  59. $token = $this->rememberMeServices->autoLogin($request);
  60. if (null === $token) {
  61. return false;
  62. }
  63. $request->attributes->set('_remember_me_token', $token);
  64. // the `null` return value indicates that this authenticator supports lazy firewalls
  65. return null;
  66. }
  67. public function authenticate(Request $request): PassportInterface
  68. {
  69. $token = $request->attributes->get('_remember_me_token');
  70. if (null === $token) {
  71. throw new \LogicException('No remember me token is set.');
  72. }
  73. return new SelfValidatingPassport(new UserBadge($token->getUsername(), [$token, 'getUser']));
  74. }
  75. public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface
  76. {
  77. return new RememberMeToken($passport->getUser(), $firewallName, $this->secret);
  78. }
  79. public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
  80. {
  81. return null; // let the original request continue
  82. }
  83. public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
  84. {
  85. $this->rememberMeServices->loginFail($request, $exception);
  86. return null;
  87. }
  88. public function isInteractive(): bool
  89. {
  90. return true;
  91. }
  92. }