Choose the right OAuth2 flow for your application

Chanika Ruchini
Identity Beyond Borders
9 min readOct 26, 2021

OAuth 2.0 is an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service. It works by delegating user authentication to the service that hosts a user account and authorizing third-party applications to access that user account.

OAuth 2.0 uses Access Tokens. An Access Token is a piece of data that represents the authorization to access resources on behalf of the end-user. The OAuth2 specification defines four different grant types for obtaining access tokens.

  • Authorization code grant
  • Implicit grant
  • Resource owner credentials grant
  • Client credentials grant

Further there are several extended grant types for additional use cases. Deciding which grants to implement depends on the type of client the end user will be using, and the experience you want for your users. In this blog, I will give you a brief introduction to each grant type and their appropriate use cases.

Before moving forward with grant types, let’s take a look at the different OAuth Roles.

  • Resource Owner: Entity that can grant access to a protected resource. Typically, this is the end-user (User).
  • Resource Server: Server hosting the protected resources. This is the API you want to access.
  • Client: Application requesting access to a protected resource on behalf of the Resource Owner.
  • Authorization Server: Server that authenticates the Resource Owner and issues access tokens after getting proper authorization.

1. Authorization Code Grant Type

The Authorization Code Grant Type is the most widely used grant type to authorize theClient to access protected data from a Resource Server.This is a redirection based grant type and uses browser redirections for communicating with the resource server and the authorization server. It provides a few important security benefits such as the ability to authenticate the client and transmission of the access token directly to the client without passing it through the resource owner’s user-agent and potentially exposing it to others (including the resource owner).

The diagram below illustrates the Authorization Code Grant flow.

Authorization Code Grant Flow

(1) Resource owner tries to access the client application via his user agent.

(2) A client application makes an authorization request to an authorization endpoint

GET {Authorization Endpoint}
?response_type=code // - Required
&client_id={Client ID} // - Required
&redirect_uri={Redirect URI} // - Optional
&scope={Scopes} // - Optional
&state={Arbitrary String} // - Recommended
HTTP/1.1
HOST: {Authorization Server}

(3) The authorization server authenticates the resource owner (via browser).

(4) Authorization Server sent a temporaryAuthorization Code back to the Redirect URI which was defined in the GET request.

HTTP/1.1 302 Found
LOCATION : {REDIRECT URI}
?code={AUTHORIZATION CODE}
&state={STATE}

(5) Then client application makes a token request(post) to a token endpoint with the authorization code.

POST (Token Endpoint)
Authorization : Basic <BASE64({CLIENT ID}:{CLIENT SECRET})> grant_type=authorization_code
&code={AUTHORIZATION CODE}
&redirect_uri={REDIRECT URI}

(6) If the token request is valid, Authorization Server returns with an access token, expiration time, refresh token and any other application specific parameters:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
“access_token” : {ACCESS TOKEN},
“token_type” : {TOKEN TYPE >> Bearer},
“refresh_token” : {REFRESH TOKEN},
“expires_in” : {Lifetime in seconds}
}

(7) Finally, the client application will use the access token for requesting resources hosted on the resource server.

The code exchange step ensures that an attacker isn’t able to intercept the access token, since the access token is always sent via a secure backchannel between the application and the OAuth server.

When to use the Authorization Code Flow

The Authorization Code flow is most commonly use in web applications which can securely store the client credentials without being exposed to the client application that runs on a web browser.

If you’re using the Authorization Code flow in a mobile app, or any other type of application that can’t store a client secret, then you have to use flow extensions like PKCE to enhance the security.

2. Implicit Grant

The implicit grant is similar to the authorization code grant, but there are two major differences.

  1. It is intended for use with user-agent-based clients (Example:SPA) which cannot securely store itsclient secret(Because all of the application code and storage is easily accessible
  2. Instead of the authorization server returning an authorization code which is exchanged for an access token, the authorization server returns an access token.

When issuing an access token during the implicit grant flow, the
authorization server does not authenticate the client. In some
cases, the client identity can be verified via the redirection URI
used to deliver the access token to the client. The access token may
be exposed to the resource owner or other applications with access to
the resource owner’s user-agent. In this flow a refresh token is not issued and if required to extend the validity of the access token, the client must use alternative methods such as silent refresh.

The diagram below illustrates the implicit grant flow.

Implicit Grant Flow

(1) Resource owner tries to access the client application via his user agent.

(2) The client application will make an authorization request to the authorization endpoint in the authorization server.

GET {Authorization Endpoint}
?response_type=token // — Required
&client_id={Client ID} // — Required
&redirect_uri={Redirect URI} // — Optional
&scope={Scopes} // — Optional
&state={Arbitrary String} // — Recommended

(3) The authorization server authenticates the resource owner (via browser).

(4) Once the authentication is successful, the authorization server will respond with access token in the URL fragment.

HTTP/1.1 302 Found
LOCATION : {REDIRECT URI}
#access_token={ACCESS TOKEN}
&token_type={TOKEN TYPE >> Bearer}
&expires_in={EXPIRES IN}
&state={STATE}

(5) Then the client application will use the access token for requesting resources hosted on the resource server.

When to use the Implicit Grant flow

The implicit grant type is previously recommended for native apps and JavaScript apps where the access token was returned immediately without an extra authorization code exchange step

But due to modern browser technologies and security threats this grant type is no longer recommended. and authorization code is used with modifications over implicit grant type. Public clients such as native apps and JavaScript apps should now use the authorization grant flow with the PKCE extension instead.

3. Resource Owner Password Credentials Grant

The Resource Owner Password Credentials Grant Type uses the username and the password credentials of a Resource Owner (user) to authorize and access protected data from a Resource Server. This can be used directly as an authorization grant to obtain an access token.

The diagram below illustrates the password grant flow.

Resource Owner Password Credentials Grant Flow

(1) The resource owner provides the client with its username and
password.

(2) The client application makes a token request to the authorization server’s token endpoint by providing the client credentials in the Authorization header, and the grant type, user credentials in the message body.

POST {Token Endpoint} HTTP/1.1
Host: {Authorization Server}
Authorization : Basic <BASE64({CLIENT ID}:{CLIENT SECRET})> Content-Type: application/x-www-form-urlencoded
grant_type=password
&username={USERNAME} // - Required
&password={PASSWORD} // - Required
&scope={SCOPES} // - Optional

(3) The authorization server authenticate the client and resource owner and respond with an access token, token expiration time, refresh token and any other application specific parameters.

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "{Access Token}",
"token_type": "{Token Type}",
"expires_in": {Lifetime In Seconds},
"refresh_token": "{Refresh Token}"
}

(4) The client application use the access token for requesting resources hosted on the resource server:

When to use the Resource Owner Password Credentials Grant flow

Password grant type is suitable in cases where the resource owner has a trust relationship with the client, such as the device operating system or a highly privileged applications and when other authorization grant types are not
available (such as an authorization code).

4. Client Credentials Grant

The Client Credentials Grant Type might be the simplest grant in OAuth2 specification and this uses the client_id and the client_secret credentials of a Client to authorize and access protected data from a Resource Server.

The diagram below illustrates the Client Credentials grant flow.

Client Credentials Grant Flow

(1) The client application makes a token request to the authorization server by providing the client credentials in the Authorization header and the grant type in the message body.

POST {Token Endpoint} HTTP/1.1
Host: {Authorization Server}
Authorization: Basic <BASE64({CLIENT ID}:{CLIENT_SECRET})>
Content-Type: application/x-www-form-urlecoded grant_type=client_credentials // - Required
&scope={Scopes} // - Optional

(2) The authorization server authenticates the client, and issues an access token.

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache{
"access_token": "{Access Token}",
"token_type": "{Token Type}",
"expires_in": {Lifetime In Seconds}
}

(3) Then the client application will use the access token for requesting resources hosted on the resource server.

When to use the Client Credentials Grant flow

Client credential grant type has been designed to be used for machine to machine communication where the end user identification is not necessary for resource authorization.

This is used when the end user (resource owner) and client application are same or is requesting access to protected resources based on an authorization previously arranged with the authorization server.

5. Refresh Token Grant

The Refresh Token grant type is used by clients to exchange a refresh token for an access token when the access token has expired. When an access token is obtained using authorization code grant type or client credentials grant type, to give additional security it has been designed to expire after the given token expiration time. In this case without end users interaction, authorization server will validate the refresh token and issue a new access token.

The following is a sample HTTP POST request for obtaining a new access token using the refresh token.

POST (Token Endpoint) HTTP/1.1
Host: {Authorization Server}
Authorization : Basic <BASE64({CLIENT ID}:{CLIENT SECRET})> grant_type=refresh_token
refresh_token={REFRESH TOKEN}
scope={SCOPES}

As a response, the Authorization server respond with a new access token and a refresh token and any other application specific parameters

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token" : {ACCESS TOKEN},
"refresh_token" : {REFRESH TOKEN},
"expires_in" : {Lifetime in seconds},
"token_type" : {TOKEN TYPE >> Bearer}
}

…..

I think now you have a clear understanding about OAuth2 grant types and usages. Selection of which grant type should be based on the requirements for end user identification, client type (server side web application, native application, client side web application) and the level of trust the resource owner would have on the client application. The flowing flow chart summarizes the above mentioned points and will help you more to grab the concepts.

Grant selection chart : Reference: https://alexbilbie.com/guide-to-oauth-2-grants/

First party or third party client?

  • A first party client : A client that you trust enough to handle the end user’s authorization credentials.
  • A third party client : A client that you don’t trust.

Access Token Owner?

  • If you are authorizing a machine to access resources and you don’t require the permission of a user to access resources you should implement the Client Credential Grant.
  • If you require the permission of a user to access resources you need to determine the client type.

Client Type?

  • If the client is a web application that has a server side component then you should implement the Authorization Code Grant Type.
  • If the client is a web application that has runs entirely on the front end (e.g. SPA) or a native application such as a mobile app you should implement the Authorization Code Grantwith the PKCE extension.
  • Third party native applications should use the Authorization Code Grant (via the native browser, not an embedded browser).

……

I hope this blog will help you to understand more about OAuth 2.0 grant types and get a clearer picture of which grant type should be used in your flow. For more details, you can refer to the specification.

Thank you for reading!

References

--

--