Skip to content
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

Refreshing a revoked access token throws an error 500 #585

Open
Maximilien-R opened this issue Apr 21, 2018 · 14 comments
Open

Refreshing a revoked access token throws an error 500 #585

Maximilien-R opened this issue Apr 21, 2018 · 14 comments

Comments

@Maximilien-R
Copy link

When you revoke an access token and try to refresh it afterwards, you end up with an error 500.

This seems to be related to the get_original_scopes method of oauth2_provider/oauth2_validators.py which tries to retrieve the access token related to the refresh token. However, since it was revoked, it no longer exists and Django throws a DoesNotExists error which isn't catch.

When we revoke an access token, maybe we should revoke refresh tokens too ? Or we could add a clause to the queryset on validate_refresh_token method to exclude refresh token without access_token.

@cheenan
Copy link

cheenan commented May 30, 2018

As a stopgap, could you do something like the following:

    token_model = oauth2_provider.models.get_refresh_token_model()
    tokens = oauth2_provider.models.RefreshToken.objects.all()
    for token in tokens:
        token.delete()

This would of course be for revoking every refresh token (I haven't tested it but it works for access tokens at least, if you replace the "refresh"s with "access")

@raphaelm
Copy link

I've also ran into this. It looks like this cannot be mitigated without adding the scope to the RefreshToken model as well?

@raphaelm
Copy link

raphaelm commented Jun 4, 2018

We're mitigating like this on our access token model currently:

    def revoke(self):
        self.expires = now() - timedelta(hours=1)
        self.save(update_fields=['expires'])

raphaelm added a commit to pretix/pretix that referenced this issue Jun 5, 2018
- [x] Application management
  - [x] Link
  - [ ] Tests
- [x] Authorize flow
  - [x] Tests
- [x] Refresh token handling
  - [x] Tests
- [x] Revocation endpoint
  - [x] Tests
  - [x] Mitigate: jazzband/django-oauth-toolkit#585
- [x] API authenticator / permission driver
  - [x] Test
- [x] Enforce organizer restriction
  - [x] Tests
- [x] Enforce scope restriction
  - [x] Tests
- [x] Show current applications to user
  - [x] Revoke
  - [x] Tests
- [x] Log new authorizations
  - [x] notify user
- [x] Ensure other grant types are not available
- [x] Documentation
- [x] check if revoking access toking, then refreshing gets rid of organizer constraint
- [x] Show logentry foo
robrap added a commit to robrap/django-oauth-toolkit that referenced this issue Jul 10, 2018
fixes jazzband#585

Note that there are no integration tests, so the unit tests don't
actually show the 500 error that would have been seen with a call
to oauth2_provider/oauth2_backends.py:create_token_response.
@robrap
Copy link
Contributor

robrap commented Jul 11, 2018

I've implemented a fix for this: #620

robrap added a commit to robrap/django-oauth-toolkit that referenced this issue Jul 11, 2018
fixes jazzband#585

Note that there are no integration tests, so the unit tests don't
actually show the 500 error that would have been seen with a call
to oauth2_provider/oauth2_backends.py:create_token_response.
@robrap
Copy link
Contributor

robrap commented Jul 11, 2018

FYI: My fix turned out to not be a fix, because I just replicated a bug in 0.12.0 that would return a 401.

I think the real fix would be to allow the refresh token, which itself was not revoked, to continue to work. I'm not sure of the correct fix, but it might be to store the refresh token's scope, and not rely on an associated access token to determine the original scope.

@raphaelm
Copy link

I think the real fix would be to allow the refresh token, which itself was not revoked, to continue to work. I'm not sure of the correct fix, but it might be to store the refresh token's scope, and not rely on an associated access token to determine the original scope.

That would be option A, option B would be adding a revoked attribute to access tokens and revoke them by setting that instead of deleting them. Not sure which one is better.

@robrap
Copy link
Contributor

robrap commented Jul 12, 2018

Agreed. Not sure which approach is better. I need to move on, but hopefully this is more clear for someone to pick up.

@keattang
Copy link

keattang commented Jan 2, 2020

Any progress on this? I have just run into this myself upgrading from 1.0.0 to 1.2.0. I'd be happy to try and make a PR if someone can point me in the right direction.

@robrap
Copy link
Contributor

robrap commented Jan 2, 2020

No progress that I am aware of.

The options continue to be:
Option A: Redundantly store the original scope with the revoke token and use this rather than trying to reference the related access token.
Option B: Store "revoked" status with the access token and update its status, rather than deleting, when revoked.

See my previous PR if you want much more detail around the bug with code references: #620.

Good luck @keattang.

@keattang
Copy link

keattang commented Jan 2, 2020

@robrap Is there a consensus on which to go with? I'd prefer not to write something and then it be decided that it's not the correct approach

@robrap
Copy link
Contributor

robrap commented Jan 2, 2020

Not sure if @jleclanche could give thumbs-up on an approach before you start. I agree with wanting to know which way to go first.

@jleclanche
Copy link
Member

I don't have an ultimate say on DOT, but option B sounds better to me.

@MattBlack85 MattBlack85 added this to the 1.4.0 milestone Oct 23, 2020
@MattBlack85
Copy link
Contributor

related to #839

@n2ygk n2ygk removed this from the 1.5.0 milestone Mar 12, 2021
@ShaheedHaque
Copy link
Contributor

I don't have an ultimate say on DOT, but option B sounds better to me.

Assuming option B is taken, can I take it that the cascade would be changed from null-on-cascade to delete-on-cascade?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants