11
11
12
12
namespace Symfony \Component \Security \Http \Authenticator ;
13
13
14
+ use Psr \Log \LoggerInterface ;
14
15
use Symfony \Component \HttpFoundation \Request ;
15
16
use Symfony \Component \HttpFoundation \Response ;
16
17
use Symfony \Component \Security \Core \Authentication \Token \RememberMeToken ;
17
18
use Symfony \Component \Security \Core \Authentication \Token \Storage \TokenStorageInterface ;
18
19
use Symfony \Component \Security \Core \Authentication \Token \TokenInterface ;
19
20
use 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 ;
20
24
use Symfony \Component \Security \Http \Authenticator \Passport \Badge \UserBadge ;
21
25
use Symfony \Component \Security \Http \Authenticator \Passport \PassportInterface ;
22
26
use 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 ;
24
30
25
31
/**
26
32
* The RememberMe *Authenticator* performs remember me authentication.
27
33
*
28
34
* 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
30
36
* then "re-authenticates" the user using the information in the
31
37
* cookie.
32
38
*
37
43
*/
38
44
class RememberMeAuthenticator implements InteractiveAuthenticatorInterface
39
45
{
40
- private $ rememberMeServices ;
46
+ private $ rememberMeHandler ;
41
47
private $ secret ;
42
48
private $ tokenStorage ;
43
- private $ options = [];
49
+ private $ cookieName ;
50
+ private $ logger ;
44
51
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 )
46
53
{
47
- $ this ->rememberMeServices = $ rememberMeServices ;
54
+ $ this ->rememberMeHandler = $ rememberMeHandler ;
48
55
$ this ->secret = $ secret ;
49
56
$ this ->tokenStorage = $ tokenStorage ;
50
- $ this ->options = $ options ;
57
+ $ this ->cookieName = $ cookieName ;
58
+ $ this ->logger = $ logger ;
51
59
}
52
60
53
61
public function supports (Request $ request ): ?bool
@@ -57,33 +65,34 @@ public function supports(Request $request): ?bool
57
65
return false ;
58
66
}
59
67
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 ;
65
70
}
66
71
67
- $ token = $ this ->rememberMeServices ->autoLogin ($ request );
68
- if (null === $ token ) {
72
+ if (!$ request ->cookies ->has ($ this ->cookieName )) {
69
73
return false ;
70
74
}
71
75
72
- $ request ->attributes ->set ('_remember_me_token ' , $ token );
76
+ if (null !== $ this ->logger ) {
77
+ $ this ->logger ->debug ('Remember-me cookie detected. ' );
78
+ }
73
79
74
80
// the `null` return value indicates that this authenticator supports lazy firewalls
75
81
return null ;
76
82
}
77
83
78
84
public function authenticate (Request $ request ): PassportInterface
79
85
{
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 . ' );
83
89
}
84
90
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
+ }));
87
96
}
88
97
89
98
public function createAuthenticatedToken (PassportInterface $ passport , string $ firewallName ): TokenInterface
@@ -98,7 +107,15 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token,
98
107
99
108
public function onAuthenticationFailure (Request $ request , AuthenticationException $ exception ): ?Response
100
109
{
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
+ }
102
119
103
120
return null ;
104
121
}
0 commit comments