1111
1212namespace Symfony \Component \Security \Http \Authenticator ;
1313
14+ use Psr \Log \LoggerInterface ;
1415use Symfony \Component \HttpFoundation \Request ;
1516use Symfony \Component \HttpFoundation \Response ;
1617use Symfony \Component \Security \Core \Authentication \Token \RememberMeToken ;
1718use Symfony \Component \Security \Core \Authentication \Token \Storage \TokenStorageInterface ;
1819use Symfony \Component \Security \Core \Authentication \Token \TokenInterface ;
1920use Symfony \Component \Security \Core \Exception \AuthenticationException ;
21+ use Symfony \Component \Security \Core \Exception \CookieTheftException ;
22+ use Symfony \Component \Security \Core \Exception \UnsupportedUserException ;
23+ use Symfony \Component \Security \Core \Exception \UsernameNotFoundException ;
2024use Symfony \Component \Security \Http \Authenticator \Passport \Badge \UserBadge ;
2125use Symfony \Component \Security \Http \Authenticator \Passport \PassportInterface ;
2226use Symfony \Component \Security \Http \Authenticator \Passport \SelfValidatingPassport ;
23- use Symfony \Component \Security \Http \RememberMe \RememberMeServicesInterface ;
27+ use Symfony \Component \Security \Http \RememberMe \RememberMeDetails ;
28+ use Symfony \Component \Security \Http \RememberMe \RememberMeHandlerInterface ;
29+ use Symfony \Component \Security \Http \RememberMe \ResponseListener ;
2430
2531/**
2632 * The RememberMe *Authenticator* performs remember me authentication.
2733 *
2834 * This authenticator is executed whenever a user's session
29- * expired and a remember me cookie was found. This authenticator
35+ * expired and a remember- me cookie was found. This authenticator
3036 * then "re-authenticates" the user using the information in the
3137 * cookie.
3238 *
3743 */
3844class RememberMeAuthenticator implements InteractiveAuthenticatorInterface
3945{
40- private $ rememberMeServices ;
46+ private $ rememberMeHandler ;
4147 private $ secret ;
4248 private $ tokenStorage ;
43- private $ options = [];
49+ private $ cookieName ;
50+ private $ logger ;
4451
45- public function __construct (RememberMeServicesInterface $ rememberMeServices , string $ secret , TokenStorageInterface $ tokenStorage , array $ options )
52+ public function __construct (RememberMeHandlerInterface $ rememberMeHandler , string $ secret , TokenStorageInterface $ tokenStorage , string $ cookieName , LoggerInterface $ logger = null )
4653 {
47- $ this ->rememberMeServices = $ rememberMeServices ;
54+ $ this ->rememberMeHandler = $ rememberMeHandler ;
4855 $ this ->secret = $ secret ;
4956 $ this ->tokenStorage = $ tokenStorage ;
50- $ this ->options = $ options ;
57+ $ this ->cookieName = $ cookieName ;
58+ $ this ->logger = $ logger ;
5159 }
5260
5361 public function supports (Request $ request ): ?bool
@@ -57,33 +65,34 @@ public function supports(Request $request): ?bool
5765 return false ;
5866 }
5967
60- // if the attribute is set, this is a lazy firewall. The previous
61- // support call already indicated support, so return null and avoid
62- // recreating the cookie
63- if ($ request ->attributes ->has ('_remember_me_token ' )) {
64- return null ;
68+ if (($ cookie = $ request ->attributes ->get (ResponseListener::COOKIE_ATTR_NAME )) && null === $ cookie ->getValue ()) {
69+ return false ;
6570 }
6671
67- $ token = $ this ->rememberMeServices ->autoLogin ($ request );
68- if (null === $ token ) {
72+ if (!$ request ->cookies ->has ($ this ->cookieName )) {
6973 return false ;
7074 }
7175
72- $ request ->attributes ->set ('_remember_me_token ' , $ token );
76+ if (null !== $ this ->logger ) {
77+ $ this ->logger ->debug ('Remember-me cookie detected. ' );
78+ }
7379
7480 // the `null` return value indicates that this authenticator supports lazy firewalls
7581 return null ;
7682 }
7783
7884 public function authenticate (Request $ request ): PassportInterface
7985 {
80- $ token = $ request ->attributes ->get (' _remember_me_token ' );
81- if (null === $ token ) {
82- throw new \LogicException ('No remember me token is set . ' );
86+ $ rawCookie = $ request ->cookies ->get ($ this -> cookieName );
87+ if (! $ rawCookie ) {
88+ throw new \LogicException ('No remember- me cookie is found . ' );
8389 }
8490
85- // @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
86- return new SelfValidatingPassport (new UserBadge (method_exists ($ token , 'getUserIdentifier ' ) ? $ token ->getUserIdentifier () : $ token ->getUsername (), [$ token , 'getUser ' ]));
91+ $ rememberMeCookie = RememberMeDetails::fromRawCookie ($ rawCookie );
92+
93+ return new SelfValidatingPassport (new UserBadge ($ rememberMeCookie ->getUserIdentifier (), function () use ($ rememberMeCookie ) {
94+ return $ this ->rememberMeHandler ->consumeRememberMeCookie ($ rememberMeCookie );
95+ }));
8796 }
8897
8998 public function createAuthenticatedToken (PassportInterface $ passport , string $ firewallName ): TokenInterface
@@ -98,7 +107,15 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token,
98107
99108 public function onAuthenticationFailure (Request $ request , AuthenticationException $ exception ): ?Response
100109 {
101- $ this ->rememberMeServices ->loginFail ($ request , $ exception );
110+ if (null !== $ this ->logger ) {
111+ if ($ exception instanceof UsernameNotFoundException) {
112+ $ this ->logger ->info ('User for remember-me cookie not found. ' , ['exception ' => $ exception ]);
113+ } elseif ($ exception instanceof UnsupportedUserException) {
114+ $ this ->logger ->warning ('User class for remember-me cookie not supported. ' , ['exception ' => $ exception ]);
115+ } elseif (!$ exception instanceof CookieTheftException) {
116+ $ this ->logger ->debug ('Remember me authentication failed. ' , ['exception ' => $ exception ]);
117+ }
118+ }
102119
103120 return null ;
104121 }
0 commit comments