Authentication

OAuth Grant Types: Explained

OAuth 2.0 is an open-standard authorization framework that allows services or servers to provide delegated and regulated access to their assets. OAuth grant types are methods for getting tokens to make requests to a resource server.

The grant type you choose depends on the security level, client application type, and other conditions. The most common grant type is the Authorization Code Grant. In this type, the authorization server returns a single-use authorization code to the client, which is then exchanged for an access token.

Here are some OAuth grant types that we’ll be covering extensively in this article:

  • Authorization code: The most common grant type, the authorization server returns a single-use authorization code to the client. The client then exchanges the code for an access token.
  • Implicit: The client application receives the access token immediately after the user gives their consent. This grant type is common for client-side devices where the client credentials cannot be stored securely.
  • Proof key for code exchange: The client app needs to prove to the authorization server that the authorization code is authentic. This type is security-centric.
  • Device code: Aimed at devices with limited input or display capabilities, such as smart TVs. The device displays a URL and a device code for the user. The user then logs in on a different device and enters the code, after which the device retrieves the access token.
  • Client credentials: This grant type uses the client’s credentials to access protected data from a resource server. It’s suitable for machine-to-machine authentication.
  • Refresh token: The authorization server optionally issues a refresh token to the client. The client can exchange the refresh token for an access token when the access token has expired.

Resource owner password credentials: This grant type is for highly trusted apps where resource owners share their credentials directly with the app.

What is OAuth?

Old Web Access Management (WAM) policies were rigid and not really suitable for companies that scaled up fast or had unpredictable user influxes. OAuth essentially solves the problem by decoupling decisions related to authorization from the authentication process. This helps achieve coarse grained authorization, enabling controlled and regulated access to specific APIs while building apps.

OAuth is also great because it can be integrated seamlessly into identity deprovisioning workflows, which are a crucial part of any B2B setup today. You may also want to keep some things in mind while implementing OAuth 2.0. It isn’t compatible with the older OAuth 1.0, nor is it an authentication protocol. This means that interoperability issues may arise while trying to integrate it.

Here is a quick rundown of the main actors participating in the OAuth flow. 

  • Resource Owner: This entity basically owns the data in the resource server. For instance, the Twitter owner is the Resource Owner of the account.
  • Resource Server: This is essentially that Application Programming Interface (API) that stores data the application wants to access
  • Client: This is the app that needs to access your data credentials
  • Authorization Server: This is the primary engine that drives the OAuth flow
OAuth Actors
OAuth Actors

I wish to refresh your memory and mention OpenID Connect (OIDC). This is basically an identity layer that sits atop OAuth2 to overcome it’s authorization-centric nature and make it a true solution for B2B applications and platforms. OIDC enhances OAuth 2.0 with a new signed id_token for the client and a UserInfo endpoint to fetch user attributes. 

Read More: OIDC vs SAML

Main OAuth Grant Types

Now that we have covered the basics of OAuth 2.0 and OIDC, we need to take a closer look at OAuth grant types. The grant type basically refers to the way your app gets the access token. OAuth 2.0 offers different types of grant types, with extensions also capable of defining new grant types. There is no clear cut winner when it comes to OAuth 2.0 grant types because every use case is different.

1. Authorization Code Grant

The flow between the OAuth service and client application is kickstarted via a series of browser-based HTTP requests. Once the user consents to the access request, an authorization code is granted to the client application, which communicates with the OAuth service to get an “access token.” This token is very crucial, as it allows the making of API calls to fetch the required user data.

Following this exchange, all communications (server-to-server) are performed over safe back-channels, which are established during registration with the OAuth service (also, a client_secret is generated at this time, which the client application uses to authenticate itself while sending server-to-server requests). The end-user is not exposed to these communications in any way or form. 

OAuth Authorization Code Grant
The Authorization Code Grant Flow

Since most sensitive data, like the access token and user data is not sent via the browser, this grant type is arguably the best for server-side apps.

2. Implicit Grant Type

The Implicit Grant Type was designed for applications where the token is returned directly to the browser without the need for an intermediate server step. It’s considered a simpler flow than the Authorization Code, but at the cost of lesser security.

The Implicit Grant Flow:

  1. The client sends the user to the authorization server with a request for authorization.
  2. The user authenticates with the authorization server and gives consent.
  3. Instead of returning an authorization code, the authorization server directly sends the access token as a fragment in the URL to the client’s redirect URI.
  4. The application extracts the token from the URL and uses it to access the protected resources.

This grant type is less recommended nowadays due to potential security vulnerabilities, especially in the modern web application environment. The absence of client authentication and the exposure of the token in the URL are primary concerns.

3. Proof Key for Code Exchange (PKCE)

Proof Key for Code Exchange is a security-centric OAuth grant type. The main concept behind PKCE is proof of possession. This basically means that the client app needs to prove to the authorization server that the authorization code is authentic, before getting an access token from it. The PKCE flow includes a code verifier and a code challenge, along with a code challenge method.

OAuth Proof Key for Code Exchange (PKCE)
The Proof Key for Code Exchange (PKCE) Flow

This is how the Proof Key for Code Exchange (PKCE) flow looks:

  1. The client officially dispatches the authorization request with the code_challenge and also the code_challenge_method
  2. The Authorization Server registers both the code_challenge and the code_challenge_method. It then issues the authorization code
  3. An access token request is sent by the client with the code_verifier
  4. The code_verifier is validated by the Authorization Server with the received code_challenge and the code_challenge_method. An access token is issued if the validation goes through
The need for Proof Key for Code Exchange (PKCE) primarily arose because the older version, Implicit Grant Type, was simply not secure enough. There was no authorization code involved at all, with the client application receiving the access token instantly upon getting the end-user’s consent. The entire flow used to work with browser-redirects, making it a risky proposition. 

4. Device Code Grant

The Device Code grant type is used by input-constrained devices (think IoT) in the flow to exchange a previously obtained device code for an access token. 

OAuth Device Code Grant
The Device Code Grant Flow

The device authorization flow goes as follows:

  1. The client authorization server gets a request access from the client, which also includes it’s “client identifier”
  2. End-user and device codes are issued by the authorization server. The end-user gets a verification URI
  3. The end-user is requested to utilize a user agent by the client. The end-user then needs to enter the end-user code to review the request
  4. The end-user is authenticated by the authorization server through the user agent. The end-user is then prompted to full in the user code
  5. The authorization server validates the user code provided by the user, and prompts the user to accept or decline the request
  6. The authorization server is polled by the client to verify if the user authorization is complete (device code and client identifier are included) 
  7. Once the authorization server has validated the device code received from the client, it grants access and replies with the Access Token

The Device Code grant type value is:
urn:ietf:params:oauth:grant-type:device_code

5. Client Credentials Grant

The client also has the option of requesting an Access Token using only its credentials (or other supported types of authentication if available). This becomes extremely relevant when the client is requesting access to the protected resources under its direct control, or those of another resource owner that have been previously arranged with the authorization server.

6. Refresh Token Grant 

As the name suggests, Refresh Tokens are essentially user credentials that help obtain Access Tokens. These tokens are given by the authorization server and are utilized to obtain new access tokens when the old one expires or turns invalid. Refresh Tokens can also be utilized to obtain supplementary access tokens with more dedicated purposes or more limited scope (e.g., where security is crucial).

So how does the Refresh Token Grant flow look? First, the client sends a POST request to the authorization server. The parameters may look like the following:

  • grant_type along with the value refresh_token
  • refresh_token along with the refresh token itself
  • client_id along with the the client’s ID
  • client_secret along with the client’s secret
  • scope with a space-delimited list of requested scope permissions. If required, you can also request a reduced set of scopes

Once the request is received, the authorization server usually responds with a JSON object that consists of the following properties:

  • token_type with the value Bearer
  • expires_in with an integer representing the TTL of the access token
  • access_token the access token itself
  • refresh_token a refresh token that can be used to acquire a new Access Token when the original one expires

Please note that unlike Access Tokens, Refresh Tokens are meant to be used only with authorization servers. They are never sent to resource servers.

7. Resource Owner Password Credentials 

The Resource Owner Password Credentials Grant, or simply the Password Grant, is a flow where the user shares their credentials (username and password) directly with the client application. The client then exchanges these credentials with the authorization server for an access token.

The Resource Owner Password Credentials Flow:

  1. The user provides the client with their username and password.
  2. The client requests an access token from the authorization server by sending the user’s credentials.
  3. The authorization server validates these credentials and, if valid, returns an access token to the client.
  4. The client can then use this token to access protected resources.

This grant type is considered less safe, as it involves sharing the user’s password directly with the client. Therefore, it’s recommended only for trusted clients or legacy applications where other flows are not feasible. It’s essential to ensure the application keeps the user’s credentials secure and doesn’t misuse them.

Related: Identity Management (IdM) Systems: Explained

Picking the Right OAuth Grant Types

Now that we have covered the main OAuth Grant Types and examined their characteristics, it’s also important to know when to use them. One of the first questions you should be asking yourself – Is your client a trusted first-party or a third-party one you don’t really know? This fact alone will essentially dictate the rest of your decision process and guide you towards the right choice/s.

If end-user identification is required for authorization in the resource server, and if the client is either a server-side web app (or a native one) accessed by third party users, using the Authorization Code Grant makes sense. On the other hand, if your resources are being accessed with an authorized machine, with no user permission required, you should seriously consider the Client Credentials Grant.

Pick wisely!