Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to revoke the RefreshToken and invalidate the AccessToken at the same time in Oauth2

I'm developing the authentication flow of a single page application (AngularJS + .Net MVC Json Rest API) using Owin Oauth2 (Authorization and Resource servers are the same).

I've chosen the Bearer Token route over the traditional cookie+session because I would like to stay stateless and also because the same Api will be used by a mobile app where token has less problem than the cookie.

This is the simplified flow:

  • User submits Username/Password to the server (POST over HTTPS to the TokenProvider route)
  • Owin creates an AccessToken with a claim containing a generated GUID (that will represent something like a Session Id) and some other claims.
  • Owin creates a RefreshToken.
  • Server creates an entry in the RefreshToken table with the following fields:

GUID(PK)|RefreshToken|Ticket|DateIssued|DateExpire|DateEnd

  • Server gives both the AccessToken and the RefreshToken to the client.

  • Client stores both the AccessToken and RefreshToken into the SessionStorage.

  • The client accesses the API with the AccessToken.

When AngularJS detects that the AccessToken is near to expire, it buffers all the requests and issues a grant_type refresh_token request;
the server uses the RefreshToken provided by the client and:

  • Checks if the Refresh Token is still valid from Db (DateExpire > GetTime() And DateEnd is Null)
  • Takes the Ticket from Db
  • Creates an AccessToken from the Ticket
  • Updates the DB entry with the fresh Dates, the new RefreshToken and the new Ticket (Note: the GUID remains the same)

When the client hits the logout server-side, the GUID read from the identity claim of the logged user is used to invalidate the entry on the table (DateEnd = GetTime()).
Client-side both tokens are removed from the SessionStorage.

In this way, I can revoke the RefreshToken denying any other requests to get a fresh AccessToken.

The problem with this approach is that there is a window of time when the authorization is revoked (ie: RefreshToken invalidated on DB) but the AccessToken is still valid (although for a limited frame of time).

What I'm thinking to do is to check the validity of the AccessToken on each request, taking the GUID from the user identity claims and hitting the db to check if the Refresh Token of that specific GUID is still valid.

Although it's quite trivial to make queries performing O(1), the single point of failure itself can have negative impact on the scalability and performance of the system.

Do you know another method to mitigate this problem and do you see any flaws in my approach?

like image 963
systempuntoout Avatar asked Jan 09 '23 17:01

systempuntoout


1 Answers

There is nothing wrong with your approach and it is very identical to the approach I've blogged about earlier, but my recommendation is not to do any DB checks when you send the access token.

Why you do not issue short-lived access tokens i.e (30 mins) and you wait until the access token lifetime is expired after revoking the refresh token. And on the client, you can clear the refresh token and access token from your client's local storage.

like image 103
Taiseer Joudeh Avatar answered Jan 19 '23 00:01

Taiseer Joudeh