Hi, I am using hydra v1.11.10 and I have a weird ...
# talk-hydra
m
Hi, I am using hydra v1.11.10 and I have a weird behaviour due to parallel request to refresh token. I was able to handle parallel request doing refresh token at the same time but if one of the request is late, and try to refresh the token after the new access token was introspected, it is deleting the new token. For example: 4 parallel requests: • request A: use
accessTokenA:refreshTokenA
• request B: use
accessTokenA:refreshTokenA
• request C: use
accessTokenA:refreshTokenA
• request D: use
accessTokenA:refreshTokenA
A, B, C call
/oauth2/token
with
refreshTokenA
to refresh token: B and C log error
"debug":"Unable to serialize access due to a concurrent update in another session: The request could not be completed due to concurrent access", "message":"invalid_request", "reason":"Failed to refresh token because of multiple concurrent requests using the same token which is not allowed.", "msg":"access denied
A is the only one able to refresh the token and got
accessTokenB:refreshTokenB
On my software, I am handling the case when B & C are failing, to retrieve the token refreshed by A A, B and C call
/oauth2/introspect
with the new token
accessTokenB
and they got a response
200
with body
Introspection{Active:true, Subject:"mysubject"}
Everything is fine for A, B an C Now D is late and it is calling
/oauth2/token
with
refreshTokenA
to refresh token: D got a different error:
"debug":"token_inactive", "message":"token_inactive", "reason":"Token validation failed.", "msg":"access denied"
Because D failed, like B & C, I am able to search and retrieve the token generate by request A
accessTokenB
D is now calling
/oauth2/introspect
with the new token
accessTokenB
and it got a response
200
with body
Introspection{Active:false, Subject:""}
On Hydra side, the log is
"debug":"not_found","message":"request_unauthorized","reason":"Check that you provided valid credentials in the right format.","msg":"access denied"
It seems the last call to
/oauth2/token
delete my new token
accessTokenB:refreshTokenB
Do you know if this behavior is normal for hydra ?
I think I just found the issue and implementation related to this behavior: https://github.com/ory/hydra/issues/2022 and PR : https://github.com/ory/fosite/pull/567/files#diff-e733adcae5e1fe83d4192fc112318cfd1d77b5ad76b6d71d383ae705ea29e3f2R179-R187 WIth message:
Copy code
// Reference: <https://tools.ietf.org/html/rfc6819#section-5.2.2.3>
//
//     The basic idea is to change the refresh token
//     value with every refresh request in order to detect attempts to
//     obtain access tokens using old refresh tokens.  Since the
//     authorization server cannot determine whether the attacker or the
//     legitimate client is trying to access, in case of such an access
//     attempt the valid refresh token and the access authorization
//     associated with it are both revoked.
is it possible to disable that ?
i
The following answer will not help you, but maybe it will be useful as a hint. If you are using oauth2/oidc in 1st party contex (when your application is both the client and the resource server), this is the price for it. Take look at your proxy/middleware dealing with the authorization code flow. There might be an option to ensure the corresponding instances can be synchronized to avoid parallel refresh token flow usage. In many cases it will however require architectural redesign.
m
Thank you for the answer, I tried to use session affinity and it is solved my issue since the requests are not dispatched anymore. But you are right, it will need architecture redesign 😕 I am using hydra for a long time (since 1.2) and I didn't catch this issue when the PR was done because it doesn't happen often.