-1

I'm currently writing some code to deal with oAuth (using the Azure Graph API, but I think Google APIs are similar).

To make an API call I need an Access Token, which has a lifetime of around one hour. To get the Access Token I need to first get the user to authorize my app use, which gives an Authorization Code which has a lifetime around ten minutes. At the same time as I get an Access Token, I can also get a Refresh Token, which has a lifetime of usually 90 days. Although, I can get a new Refresh Token before it expires to ensure I keep a valid Refresh Token.

So there are three types of codes/tokens to deal with.

Why are all these different codes and tokens needed? Why not just provide an authorization code with a lifetime of 90 days and be done with it?

Am I correct in assuming that if my Refresh Token expires, then I have to go right back to the beginning of the chain and request access from my user again?

  • I cannot write a long answer currently. I think this is basically an optimization. An access token is valid by itself and cannot be invalidated, so it has a short lifetime. A refresh token could be invalidated with reasonable effort/bookkeeping. – Daniel B Feb 09 '23 at 13:22

2 Answers2

1

Why are all these different codes and tokens needed? Why not just provide an authorization code with a lifetime of 90 days and be done with it?

The authorization code is one of several ways of delivering the access token – it's not a separate "step" but still part of the initial "interactive authentication" flow. It differs from the actual access token in that you also need the OAuth2 client secret (or the PKCE challenge that was generated at the beginning) to make use of the code. In theory, this means that even if the code itself is intercepted (e.g. through redirects being visible client-side), only the original app can exchange it for the real token.

There are other flows which do not use one – you could use the "implicit grant" flow to directly receive the access token, for example, or you could use a certificate to authenticate and receive the token in one step, depending on what the OAuth IDP supports.

(For example, "service accounts" in Google authenticate using an RSA keypair to get an access token – they don't use the interactive auth flow and therefore there is no auth code.)

Am I correct in assuming that if my Refresh Token expires, then I have to go right back to the beginning of the chain and request access from my user again?

Yes, but avoiding that is actually the purpose of a Refresh Token in the first place.

If you only had one type of token (an Access Token), every time it expired you would need to go right back to the beginning of the chain. This is usually avoided by having a Refresh Token which normally has a much longer lifetime, e.g. if the Access Token is valid for several hours or days, then it's common for a the Refresh Token to be valid for months or years.

I would say that 90 days for a Refresh Token is unusually short, and somewhat defeats the point of having one – my guess is that Azure OAuth2 is specifically set up that way in order to force reauthentication through a harder-to-steal credential, such as a device certificate or the custom HMAC scheme "Windows Hello" uses. (In contrast, refresh tokens issued by Google seem to have practically no expiry time at all – I've been using the same token to access Gmail IMAP for years.)

u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
  • When refreshing the token, don't you get a new refreshtoken that is valid for another 90 days? Because that would mean you'd not have to login if you refresh at least once every 90 days. Or is this provider specific? – Berend Feb 09 '23 at 12:46
  • 1
    It's Azure-specific, I believe. Google returns exactly the same refresh token every time. Can't speak for other providers though; I may be wrong. RFC 6749 says "(and optionally a refresh token)" is issued. – u1686_grawity Feb 09 '23 at 12:51
0

There are different types because they serve differnt purposes. An easy reason why you have them is because they might be compromised and used for different purposes. So having them be short lived ensures that improper handling or a compromised client, while still bad, could potentially have less impact.

It also helps by separating what does what. One token would mean you would have to just get your hands on one token and could do everything. Having multiple tokens makes it a bit harder to get your hand on the optiont to do everything.

See the RFC 6749 for more information about the token types.

Seth
  • 9,000
  • 1
  • 19
  • 34
  • But the authorization code could be different, depending upon the APIs requested and the app making the request (I suspect it already is), so there doesn't seem to be a benefit to me to having 90 day refresh tokens vs 90 day authorization codes. – Phil Rosenberg Feb 09 '23 at 11:33
  • However, that link does explain some of the reasoning. I.e, an Access Token can have fewer access rights compared to the initial authorization code. This can segregate the different access types (some of which may only be needed temporarily or occasionally) and I can see how this improves security. – Phil Rosenberg Feb 09 '23 at 11:38
  • The RFC does state that refresh tokens itself are optional. It also highlights that refresh tokens should never end up in a communicaton with a resource server. One benefit to having a refresh token is that you can act without user input and the flow to get another access token differs. As explained the whole reason is that you don't just need to grab a single code and have full control. This approach allows for more fine grained control and leave more power in the hands of the account owner. – Seth Feb 09 '23 at 12:17