OAuth 2.0 flow and Grant types

OAuth 2.0 supports several different grants. By grants we mean ways of retrieving an access token. Deciding which one is suited for your case depends mostly on your Client's type, but other parameters weigh in as well, like the level of trust for the Client, or the experience you want your users to have.

Follow this flow to identify the grant that best matches your case:

oauth2.0flow.png

Terminology

Resource Owner: the entity that can grant access to a protected resource. Typically this is the end-user.

Client: an application requesting access to a protected resource on behalf of the Resource Owner.

Resource Server: the server hosting the protected resources. This is the API you want to access.

Authorization Server: the server that authenticates the Resource Owner, and issues access tokens after getting proper authorization. In this case, Auth0.

User Agent: the agent used by the Resource Owner to interact with the Client, for example a browser or a native application.

 

Is the Client the Resource Owner?
The first decision point is about whether the party that requires access to resources is a machine. In this case of machine to machine authorization, the Client is also the Resource Owner. No end-user authorization is needed in this case. An example is a cron job that uses an API to import information to a database. In this example the cron job is the Client and the Resource Owner since it holds the Client Id and Client Secret and uses them to get an access token from the Authorization Server.

If this case matches your needs, then for more information on how this flow works and how to implement it refer to: Client Credentials Grant.

Is the Client a web app executing on the server?
If the Client is a regular web app executing on a server then the Authorization Code Grant is the flow you should use. Using this the Client can retrieve an access token and, optionally, a refresh token. It's considered the safest choice since the access token is passed directly to the web server hosting the Client, without going through the user's web browser and risk exposure.

If this case matches your needs, then for more information on how this flow works and how to implement it refer to: Authorization Code Grant.

Is the Client absolutely trusted with user credentials?
This decision point may result to suggesting the Resource Owner Password Credentials Grant. In this flow the end-user is asked to fill in credentials (username/password) typically using an interactive form. This information is sent to the backend and from there to Auth0. It is therefore imperative that the Client is absolutely trusted with this information.

Is the Client a native app or a SPA?
If the Client is a Single Page Application (meaning an application running in a browser using a scripting language such as Javascript) then the Implicit Grant should be used. In this case, instead of getting an authorization code that needs to be exchanged for an access token, the Client retrieves directly an access token. On the plus side, this is more efficient since it reduces the number of round trips required to get an access token. However, a security consideration is that the access token is exposed on the client side. Also, it should be noted that Implicit Grant does not return a refresh token because the browser cannot keep it private.

If the Client is a native app then the Authorization Code Grant using Proof Key for Code Exchange should be used. What this grant adds to Authorization Code Grant, is the concept of code_verifier. When at first the client asks for an Authorization Code it generates a code_verifier and its transformed value called code_challenge. The code_challenge is sent along with the request. A code_challenge_method is also sent. Afterwards, when the client wants to exchange the Authorization Code for an access token, it also sends along the code_verifier. The Authorization Server transforms this and if it matches the originally sent code challenge it returns an access token.

For more information on how this flow works and how to implement it, refer to Authorization Code Grant (PKCE).

 

Grant Types

Grant types are a way to specify how a client wants to interact with OneCOntactLogin. The OpenID Connect and OAuth 2 specs define the following grant types:

 

You can specify which grant type a client can use via the AllowedGrantTypes property on the Client configuration.

A client can be configured to use more than a single grant type (e.g. Hybrid for user centric operations and client credentials for server to server communication). The GrantTypes class can be used to pick from typical grant type combinations:

Client.AllowedGrantTypes = GrantTypes.HybridAndClientCredentials;

You can also specify the grant types list manually:

Client.AllowedGrantTypes =
{
GrantType.Hybrid,
GrantType.ClientCredentials,
"my_custom_grant_type"
};

If you want to transmit access tokens via the browser channel, you also need to allow that explicitly on the client configuration:

Client.AllowAccessTokensViaBrowser = true;

For the remainder, the grant types are briefly described, and when you would use them. It is also recommended, that in addition you read the corresponding specs to get a better understanding of the differences.

 

Client credentials
This is the simplest grant type and is used for server to server communication - tokens are always requested on behalf of a client, not a user.

With this grant type you send a token request to the token endpoint, and get an access token back that represents the client. The client typically has to authenticate with the token endpoint using its client ID and secret.

 

Resource owner password
The resource owner password grant type allows to request tokens on behalf of a user by sending the user’s name and password to the token endpoint. This is so called “non-interactive” authentication and is generally not recommended.

There might be reasons for certain legacy or first-party integration scenarios, where this grant type is useful, but the general recommendation is to use an interactive flow like implicit or hybrid for user authentication instead.

See the Resource Owner Password Quick Start for a sample how to use it. You also need to provide code for the username/password validation which can be supplied by implementing the IResourceOwnerPasswordValidator interface. 

 

Implicit
The implicit grant type is optimized for browser-based applications. Either for user authentication-only (both server-side and JavaScript applications), or authentication and access token requests (JavaScript applications).

In the implicit flow, all tokens are transmitted via the browser, and advanced features like refresh tokens are thus not allowed.

 

Authorization code
Authorization code flow was originally specified by OAuth 2, and provides a way to retrieve tokens on a back-channel as opposed to the browser front-channel. It also support client authentication.

While this grant type is supported on its own, it is generally recommended you combine that with identity tokens which turns it into the so called hybrid flow. Hybrid flow gives you important extra features like signed protocol responses.

 

Hybrid
Hybrid flow is a combination of the implicit and authorization code flow - it uses combinations of multiple grant types, most typically code id_token.

In hybrid flow the identity token is transmitted via the browser channel and contains the signed protocol response along with signatures for other artifacts like the authorization code. This mitigates a number of attacks that apply to the browser channel. After successful validation of the response, the back-channel is used to retrieve the access and refresh token.

This is the recommended flow for native applications that want to retrieve access tokens (and possibly refresh tokens as well) and is used for server-side web applications and native desktop/mobile applications.

 

Refresh tokens
Refresh tokens allow gaining long lived access to APIs.

You typically want to keep the lifetime of access tokens as short as possible, but at the same time don’t want to bother the user over and over again with doing a front-channel roundtrips to OneContactLogin for requesting new ones.

Refresh tokens allow requesting new access tokens without user interaction. Every time the client refreshes a token it needs to make an (authenticated) back-channel call to OneContactLogin. This allows checking if the refresh token is still valid, or has been revoked in the meantime.

Refresh tokens are supported in hybrid, authorization code and resource owner password flows. To request a refresh token, the client needs to include the offline_access scope in the token request (and must be authorized to request for that scope).