@@ -64,6 +64,7 @@ public function __construct(
6464 /**
6565 * @PublicPage
6666 * @NoCSRFRequired
67+ * @BruteForceProtection(action=oauth2GetToken)
6768 *
6869 * @param string $grant_type
6970 * @param string $code
@@ -76,9 +77,11 @@ public function getToken($grant_type, $code, $refresh_token, $client_id, $client
7677
7778 // We only handle two types
7879 if ($ grant_type !== 'authorization_code ' && $ grant_type !== 'refresh_token ' ) {
79- return new JSONResponse ([
80+ $ response = new JSONResponse ([
8081 'error ' => 'invalid_grant ' ,
8182 ], Http::STATUS_BAD_REQUEST );
83+ $ response ->throttle (['invalid_grant ' => $ grant_type ]);
84+ return $ response ;
8285 }
8386
8487 // We handle the initial and refresh tokens the same way
@@ -89,17 +92,21 @@ public function getToken($grant_type, $code, $refresh_token, $client_id, $client
8992 try {
9093 $ accessToken = $ this ->accessTokenMapper ->getByCode ($ code );
9194 } catch (AccessTokenNotFoundException $ e ) {
92- return new JSONResponse ([
95+ $ response = new JSONResponse ([
9396 'error ' => 'invalid_request ' ,
9497 ], Http::STATUS_BAD_REQUEST );
98+ $ response ->throttle (['invalid_request ' => 'token not found ' , 'code ' => $ code ]);
99+ return $ response ;
95100 }
96101
97102 try {
98103 $ client = $ this ->clientMapper ->getByUid ($ accessToken ->getClientId ());
99104 } catch (ClientNotFoundException $ e ) {
100- return new JSONResponse ([
105+ $ response = new JSONResponse ([
101106 'error ' => 'invalid_request ' ,
102107 ], Http::STATUS_BAD_REQUEST );
108+ $ response ->throttle (['invalid_request ' => 'client not found ' , 'client_id ' => $ accessToken ->getClientId ()]);
109+ return $ response ;
103110 }
104111
105112 if (isset ($ this ->request ->server ['PHP_AUTH_USER ' ])) {
@@ -111,15 +118,18 @@ public function getToken($grant_type, $code, $refresh_token, $client_id, $client
111118 $ storedClientSecret = $ this ->crypto ->decrypt ($ client ->getSecret ());
112119 } catch (\Exception $ e ) {
113120 $ this ->logger ->error ('OAuth client secret decryption error ' , ['exception ' => $ e ]);
121+ // we don't throttle here because it might not be a bruteforce attack
114122 return new JSONResponse ([
115123 'error ' => 'invalid_client ' ,
116124 ], Http::STATUS_BAD_REQUEST );
117125 }
118126 // The client id and secret must match. Else we don't provide an access token!
119127 if ($ client ->getClientIdentifier () !== $ client_id || $ storedClientSecret !== $ client_secret ) {
120- return new JSONResponse ([
128+ $ response = new JSONResponse ([
121129 'error ' => 'invalid_client ' ,
122130 ], Http::STATUS_BAD_REQUEST );
131+ $ response ->throttle (['invalid_client ' => 'client ID or secret does not match ' ]);
132+ return $ response ;
123133 }
124134
125135 $ decryptedToken = $ this ->crypto ->decrypt ($ accessToken ->getEncryptedToken (), $ code );
@@ -132,9 +142,11 @@ public function getToken($grant_type, $code, $refresh_token, $client_id, $client
132142 } catch (InvalidTokenException $ e ) {
133143 //We can't do anything...
134144 $ this ->accessTokenMapper ->delete ($ accessToken );
135- return new JSONResponse ([
145+ $ response = new JSONResponse ([
136146 'error ' => 'invalid_request ' ,
137147 ], Http::STATUS_BAD_REQUEST );
148+ $ response ->throttle (['invalid_request ' => 'token is invalid ' ]);
149+ return $ response ;
138150 }
139151
140152 // Rotate the apptoken (so the old one becomes invalid basically)
0 commit comments