The OAuth2.0 Protocol

Truong Loan
swile-engineering
Published in
7 min readMay 20, 2022

The OAuth2 protocol is a standard that allows a client application to have limited access to the resources of another client application.

Let’s go back to our example with Emma (article on Digital Identity) who wants to retrieve her Gmail contacts from her LinkedIn professional network, so she can add them.

OAuth2 flow

The user, Emma, connects to the LinkedIn application, which offers to synchronize her Gmail contacts and add them to her professional network.

When the user clicks on the button that offers to retrieve her Gmail contacts, she will be redirected to the login interface of her Google account.

After authenticating herself, Emma will have to authorize LinkedIn to access her contacts. In the identification process, LinkedIn did not handle the authentication of the user at all. This will be managed through by Open ID connect protocol, which will bring an additional layer to OAuth2. By adding the notion of identity, which we will see in a next article.

Emma’s password is never communicated between the two APIs (LinkedIn and Google). This involves of delegating the authentication to a third party, who will take care of checking if the user exists in its database. The Authorization Server will give an Authorization Code to the Client App, which will allow the process to continue to retrieve the user’s contacts.

The authorization system of the OAuth2 protocol relies on 4 roles to make its entire authorization system work.

OAuth2 roles

The owner of the resource: Resource owner. The person who made the request (the end user), in our case Emma.

The client: Client Application. Application or service that will request permission to access a part of the resources. Here, LinkedIn.

There are two types of Client Application:

  • The classic client or confidential client is an application that will be able to authenticate securely to the Authorization Server.
  • The public client, which, as its name suggests, will expose certain information in the browser.

The Ressource Server, the server that hosts the protected resource. It is the server that will accept, or not, to share a resource.

The Authorization Server will provide access tokens to clients. An access token is a token that allows its owner to have the right to access a resource. After confirmation of authentication by the user (Emma). The server will then give permission to the Client Application to access the user’s Gmail contacts.

Let’s go back to our example, Emma will authorize the application once to retrieve her Gmail contacts. The communication with Google’s external API will be handled by LinkedIn via OAuth2.

Before these exchanges can take place. LinkedIn has to be registered as a service (create an OAuth client) with the Authorization Server (Google API).

Google API registration flow

LinkedIn must provide registration information, such as its site name, callback URL, and scope of the authorization request before any request can be made. This registration is done at the time LinkedIn will integrate the Gmail contact synchronization button, according to the rules defined by the Google API.

Once this information has been entered, the service will be able to create an OAuth client on the Google platform. Google will give it a Client ID (client_id) and a Secret Client (client_secret).

Retrieving the client_id and client_secret

The client_id is a unique identifier that must be used to communicate with Google. While the client_secret as its name suggests, must remain secret. It is stored on the server side and will allow the Client App to authenticate itself to the Authorization Server. When requesting an access token, the Client App will generate a JWT Baerer Authorization Grant and sign it with the client_secret.

Once the LinkedIn service is registered as an OAuth client with Google. LinkedIn will be able to initiate the authorization request to the user. To ask the user if they allow the LinkedIn Application to have read access to their Gmail contacts. LinkedIn will then use the Authorization Code type.

User consent to retrieve an authorization code.

It should be noted that there are as many types of authorization (Grants types) as there are ways to connect to an Authorization server. There is a suitable type depending on the scenario you need. The different types will offer different security guarantees.

The most used type is the one we have just seen: the Authorization Code. It is also the most secure type. Authorization is based on interaction with a user on a browser. It cannot be used by a machine, or to communicate from one API to another API.

The application will take this form:

https://accounts.google.com/o/oauth2/v2/auth?client_id=CLIENT_ID&response_type=CODE&scope=contacts.readonly&redirect_uri=CALLBACK_URL&access_type=offline
  • The endpoint of the API that will manage the authorizations. (https://accounts.google.com/o/oauth2/v2/auth)
  • Then we have the client_id which will identify the application.
  • The response_type, in our example we will specify that the application wishes to obtain an Authorization Code.
  • The scope, which allows you to specify the level of access you wish to have: here we wish to read the contacts.
  • The redirect_uri is the redirection URL where the service will then redirect the user after generating an authorization code.
  • For Google, we need an offline access, which will allow communication with the Google API without the user being present on the browser. The offline access allows the Client App to obtain a refresh token, a concept that we will see a little later in the article.
OAuth2 Flow

Once Emma has authorized the Client App (LinkedIn). LinkedIn will retrieve a code (Authorization Code), and will exchange it for an access token. Earlier, we saw the notion of client_id and client_secret. The Client App will use the client_secret to authenticate itself to the Authorization server to request an access token.

As a reminder, the access token is like a ‘valet key’. A car key that you can give to a valet to park your car in a car park, without the valet having access to all the car’s functions.

The access token will allow our application (LinkedIn) to make a request on behalf of the user (Emma) to the Google API to retrieve these contacts. It allows us to request access to a protected resource, which is granted by the Resource owner and delivered by the Authorization server.

The access token often has a very limited life span. It has no particular format. Most of the time, it is a character string. The application does not need to know what is in the access token. It will retrieve the token and send it via a secure connection (HTTPS) to the Resource Server which will have to validate the request for access to the resource or refuse it.

The response to the access token request given by the Resource Server will take this form:

{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"Bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
}
  • We must have an access_token (string issued by the Authorization server)
  • We must have the token_type (Bearer).
  • The duration of the access token: expires_in which is recommended, but not mandatory.
  • The refresh_token is also optional. When the access token’s validation period is exceeded, the refresh token allows the Client APP to request another valid access token without going through the user. This improves the user experience.
  • Other parameters can be added, such as the scope. When the scope does not change from the Authorization Code, this field is optional. However, if the scope is different, it must be added (in case Emma changes the permissions she gives to LinkedIn to access her Google information).

It is possible that the request fails. There are several reasons for this, such as an invalid Authorization Code or the redirection URL not being known by the Authorization Server.

The Authorization Server will return a 400 (Bad Request). With one of these error parameters, which can be :

Bad request

It is possible to have two additional keys to help developers understand the problem:

  • error_description (which can only contain ASCII characters, one sentence or two large ones max)
  • error_uri

Now that we have an access token, the famous “valet key” we talked about in the introduction to digital identity. We are finally allowed to make our request to the Resource Server to get Emma’s Gmail contacts and display them on the LinkedIn application.🎉

Let’s say Emma hasn’t had time to add these Gmail contacts to her LinkedIn application. She returns later and wants to finalize the process. Since the access token is time limited, it is no longer valid. The Client (LinkedIn) does not need to redo all the steps. It can use the Refresh Token authorization type. It will exchange its Refresh Token for an access token. This type allows the Client App to have a valid access token without any user intervention.

The Client App will then call the Authorization Server again to request a new access token.

https://accounts.google.com/o/oauth2/token?client_id=CLIENT_ID&client_secret=SECRET_ID&grant_type=refresh_token&refresh_token=YOU_REFRESH_TOKEN

We will then receive a new access token with a new expiration date. In order to retrieve our Gmail contacts, to display them in our application.

--

--