Access Tokens are often short-lived and need renewing when they expire. This article is about how to do this and explains that Refresh Tokens are probably not what you should be using.
Renewing Access Tokens when the User is there
Single Page App (SPA)
Say we have a SPA running in a browser, which uses Access Tokens to access an API resource.
The User has to first authenticate with the OpenID Connect Provider (OCP). This involves making a request to the OCP’s Authorization Endpoint which if successful will set an Authentication Cookie and return an Identity Token and Access Token in the response.
Then the Access Token can be used in requests to a resource’s API by setting it in the request’s Authorization Header:
The Access Token is usually short-lived, so will need replacing when it expires. You might actively track the expiry in the SPA, or just keep sending it to the API until you get a 401 Unauthorized response. Either way, you will then need to get a new Access Token.
Renewing the Access Token
The correct mechanism to get a new Access Token here is simply to repeat the request you made initially to the Authorization Endpoint. Since you already have an Authentication Cookie from the OpenID Connect Provider (OCP) that proves your identity, the OCP can skip the authentication dialogue, and just return you a new set of tokens.
Eventually the Authentication Cookie will itself expire, at which point the User will be required to authenticate again before any further tokens can be issued.
Renewing Access Token when the User is not there
Using with long-running services
The use-case here is where the User wants to allow some process to do work for them, when they are not there. For example we might have an application that monitors Twitter for particular hash-tags and sends the User a notification when the tags are found.
Such a process might run for days or weeks, whereas the original Access Token might only have a lifetime measured in hours.
So we have to give the application permission to work on behalf of the User when the User is offline.
The mechanism to do this is to include an
offline_access scope when the User makes the initial request to the Authorization Endpoint. This will return a Refresh Token (in addition to the Identity and Access Tokens).
New Access Tokens can then be requested by making requests to the OCP’s Token Endpoint, including the Refresh Token in the request.
But here we have a potential security problem. If the Refresh Token gets hijacked somehow a malicious User could keep requesting Access Tokens and gain perpetual access to another User’s resources.
For this reason, Refresh Tokens should only be issued to server-side Clients that we control, and never to Clients out in the wild (like a SPA in a browser) where hijacking a token is at least possible.
This means Refresh Tokens should only be requested when using Authorization Code Flow (or the equivalent server-side part of Hybrid Flow).
In the simplified Authorization Code Flow diagram below the key thing to note is that only the completely opaque (meaningless) Authorization Code is passed around the public parts of the system. Only the Client that requested the Refresh Token (the Web Application) is allowed to exchange the Authorization Code for the tokens over a secure back-channel:
Using the Refresh Token
Once the Refresh Token is received it can then be passed to whatever trusted-service that is going to be running on behalf of the User.
Whenever the Access Token expires, the service can then request a new one from the OCP, and provided the User has not been revoked, or the granted permissions changed, a new one will be issued:
Of course, SSL should be used for all requests in this process, eliminating the chance of the token being hijacked during communication between our trusted systems.