-
-
Notifications
You must be signed in to change notification settings - Fork 368
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: allow for permanent refresh_token(s) #632
feat: allow for permanent refresh_token(s) #632
Conversation
This introduces the ability to set a boolean context value with key `EnableOneTimeUseRefreshTokenKey` that, when set, will disable refresh_token revocation. If the value is missing refresh_token revocation will still be performed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Man, I wrote a really long review that somehow did not make it through? Sorry about that! So here's the same review and I will double check if GitHub overlords saved it ;)
I think the change is really good from a code perspective. Unfortunately, it is counterintuitive to security best practices laid out in the IETF RFCs, in particular https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.13.2 and other sections in this RFC.
As we do not support sender-constrained refresh tokens (apparently that's a new RFC), we need to implement Refresh token rotation if we want to follow this RFC's recommendations (which we do).
So what alternative do we have? I think you've already figured it out!
Instead of hard-deleting/revoking the token we should probably set an expiry time that is a configured amount of seconds in the future. For example, you set the "refresh token replace grace period" to 5 seconds. When the RT is used, it will be valid for another 5 seconds, and only then will it actually be considered inactive!
What's great about this, you probably don't even need to make changes in fosite. It could all be in the implementation of Ory Hydra's persister!
What do you think about this idea?
Upon further consideration I arrived at the same conclusion; adding the grace period and continuing rotation will be a safer change. I will probably close both of the PRs for this and start a new one. |
Awesome, thank you for your hard work! |
closing in favor of refresh token grace period |
This is a branch of
v0.40.2
that introduces the ability to disable one-time-use refresh tokens (RT). From my reading of issues here in the fosite repository and the Hydra repository, a number of users desire a feature like this. My hope is that this change can be released with a new versionv0.40.3
and a new version of Hydrav1.10.7
. With these new releases I can update my deployment of Hydra to pick up the new feature.One time use refresh-tokens can introduce issues where a user's "session" stored in a 3rd party database can be completely disabled, forcing the end-user to go through an OAuth2 flow with Hydra again. The related issues I have included below outline some of the ways this can happen and include some discussion.
For brevity here is a use case involving threads that can permanently disable a session:
access_token
(AT-0) andrefresh_token
(RT-0)./userinfo
)This can be worked-around by implementing a distributed-lock pattern in the client to Hydra, but I believe this places an undue burden on the client developers. This burden is exacerbated by the nature of implementing OAuth2 flows for an application: each client will likely be an independent 3rd party entity to the entity hosting Hydra. Further, a distributed-locking pattern can not account for the other failure cases, such as network errors.
Note: There is a companion PR in Hydra that adds a configuration option to enable/disable this behavior.
Related issue(s)
#255
Hydra #1831
Checklist
and signed the CLA.
vulnerability. If this pull request addresses a security vulnerability, I
confirm that I got green light (please contact
security@ory.sh) from the maintainers to push
the changes.
works.
appropriate).
Further comments
I implemented this change with the goal of changing as little as possible, hence the use of
Context
to pass information from Hydra to this library. I have seen no other mechanism for accessing configuration provided in Hydra to fosite, nor is the Strategy Pattern possible here, asHandleTokenEndpointRequest
does not use a strategy for revoking a token. InsteadHandleTokenEndpointRequest
accessesTokenRevocationStorage
directly, meaning that this behavior is applied to every Strategy involved. A deeper change could be made to introduce a higher-level strategy for handling token refresh, or introducing a TokenRevocation strategy but this is in conflict with my goal of making a small, precise, change.