When To Use Which (OAuth2) Grants and (OIDC) Flows

If you have been following my SAML2 vs JWT series lately, you are no doubt familiar with the OAuth2 and OpenID Connect (OIDC) specifications . The OAuth2 specification defines several authorization grants that can be used to coordinate authentication of a user and grant access to resources owned by that user. Of course, in the earlier OAuth2 post, we discussed how OAuth2 is an authorization protocol that doesn’t define the specifics of how the authentication occurs, but any complete implementation will support a variety of authentication mechanisms. These grants include:

  • Authorization Code Grant
  • Implicit Grant
  • Resource Owner Password Credential Grant
  • Client Credential Grant

The OIDC spec adds to this list by providing a set of authentication flows including:

  • Authorization Code Flow
  • Implicit Flow
  • Hybrid Flow

The OAuth2 family of specs define several extension grants (that we explore here) that we will explore when to use in a future post.

We explored relatively generic use cases in my earlier blog posts; it may have left you wondering when each of these mechanisms should be used. When I was first exposed to these concepts several years ago, I struggled with that as well.

So, in this blog post, we are going to explore exactly when each of these should be used — including some instances of where these could be used, but maybe cause more problems then they solve. I covered some of this information in my earlier posts, but that wasn’t the primary focus and the discussion is incomplete.

Another note, worth mentioning, before diving into the details is that most Identity Providers (OAuth2 Authorization Servers and OIDC OpenID Providers) now offer libraries and SDKs that allow this functionality to be used without being aware of all the low-level details. Regardless of whether such a library is available for your IdP, the supported features of your IdP will dictate more than anything else what OAuth2 and OIDC features are used — choose wisely with an understanding of your expected use cases.

The recommendations in this post are briefly summarized here. For each of the following client types (where end user authentication is required), the following grants and flows should be used (generally, with a preference towards the OIDC option, if available).

Web Application (with dedicated server-side component): OAuth2 Authorization Code Grant (with Confidential Client), OIDC Authorization Code Flow (with Confidential Client)

Desktop Native Application: Authorization Code Grant (with Public Client and PKCE), OIDC Authorization Code Flow (with Public Client and PKCE)

Mobile Native Application: Authorization Code Grant (with Public Client and PKCE), OIDC Authorization Code Flow (with Public Client and PKCE)

SPA App: OAuth2 Implicit Grant, OIDC Implicit Flow

Javascript application: OAuth2 Implicit Grant, OIDC Implicit Flow

Anytime you have a system that isn’t concerned with the end user identity (and just needs to authenticate the system), use the OAuth2 Client Credential Grant.

From a purely technical point of view, most of the OAuth2 grants and OIDC flows that support end user authentication can be made to work in just about any scenario, but there tend to be profound security (or lack thereof) implications to being creative in this fashion.

For the other grants and flows, read below.

OAuth2 Spec

The OAuth2 spec (Section 2.1) describes three types of clients:

  • native applications (across a variety of devices including desktop, phone, tablet, etc) — typically, a public client.
  • user-agent-based applications (JavaScript-based applications and SPA apps for our purposes) — typically, a public client.
  • web applications (traditional web application architecture) — typically, a confidential client

Plenty of applications will not fit into exactly one of these categories. Individual situations will have to be evaluated on their own merits.

Any time we discuss resources below, this could be anything of value that is accessible on the network — data store, web application, API (my favorite example), static content, etc.

Things to Consider:

  • Public versus confidential clients
  • You own/control the app vs. third-party owns/controls the app
  • Type of Client: Web Application, Native App, User-Agent-based app
  • End user or application identity (or both)
  • Desire to have a centrally-managed login workflow with a common look and feel.

Additional information about the mechanics of the OAuth2 grants can be found here.

OAuth2 — Authorization Code Grant

OAuth2 Authorization Code Grant

This is usually targeted at web applications or other systems that have a server-side component that can act as a Confidential Client (keep the client secret secure). The end result is that the end user and user agent do not see the OAuth2 Access Token or any other information that may be contained in the OAuth2 Authentication Response and allows for the client and the end user to be authenticated.

So, the Authorization Code Grant works great for the traditional Web Application architecture that has a dedicated server-side component. It can also work in most situations where there is a secure, server-side component that can act in the role of the Client.

With modern SPA apps, native mobile apps, and others this may not be the case — the server-side component may be a shared API Gateway for example that isn’t really meant to fill this role and may not be under your direct control (ergo, you don’t want it to know the client secret for your application). Thus, these are categorized as Public Clients. It’s also interesting to note that the “Client” terminology is used to describe the component closest to the end user in these scenarios, not the server-side component — as is the case with the “default” Authorization Code Grant example.

The OAuth2 specification does allow for a Public Client to use the Authorization Code Grant. Though, something is lost in terms of the level of security assurance when you are no longer authenticating the client (via client identifier and client secret). With this ability, it is possible to use the Authorization Code Grant with SPA apps and native mobile apps. Though, potential attack vectors are introduced without the client secret in play; to mitigate this issues, consider using the OAuth2 Proof Key for Code Exchange Spec that allows dynamic client secrets to be generated, which allows the Authorization Server to bind the authorization code exchange request to the original authorization code request.

When this grant is used (with a public client) by a native application, the prevailing methodology is to launch an external browser to handle the user’s interaction with the login workflow. Then, the native application itself does not see the user’s credential. A user-agent library that can handle the request/response processing could also be used, though this could result in the client application seeing the password.

Use Case: authentication of end users and access by client to a resource (possibly owned by the end user)

Used By: Web Applications (that have a server-side component that can keep the the client secret confidential), native apps (with a public client and PKCE)

Additional Use Cases: If you want to introduce refresh tokens to a situation where you wouldn’t otherwise have them (such as with the Implicit Grant) and the other requirements mentioned above are satisfied, this grant could potentially be used. Though, this is stated as a purely technical observation and is not a good practice or even necessarily secure.

OAuth2 — Implicit Grant

OAuth2 Implicit Grant

The Implicit Grant has the benefit of requiring only a single call to the IdP; however, it opens up security concerns that are not present in the other grants — namely, the user agent can now see the access token. This grant also lacks the ability to authenticate the the client, which the other grants can do — further introducing attack vectors that the authorization grants, which require a client secret, do not experience.

Refresh tokens are not supported.

Use Case: authentication of end users and access by client to a resource (possibly owned by the end user).

Used By: SPA Apps (and any other Javascript/User-agent-based app)

Additional Uses: Earlier in the life of OAuth2, the Implicit Grant tended to be recommended for native applications (especially native mobile apps). More recently, the Authorization Code Grant (with public client and PKCE) is typically recommended for use with native apps. Though, using the Implicit Grant is still technically feasible.

OAuth2 — Resource Owner Password Credential Grant

OAuth2 Resource Owner Password Credential Grant

Like the Implicit Grant, this grant also has the benefit of only making a single call to the authorization server. It allows an application that is incapable of integrating with an interactive login (such as you get with the Implicit Grant and Authorization Grant). This gives the authorization server a great deal of flexibility in terms of the types of clients that can interact with it, but it also provides a mechanism for bypassing a standardized login workflow mechanism that can enforce things like two-factor authentication, forced password resets, and similar desirable identity features. From the perspective of a centralized identity stack, bypassing these features is counterproductive and undesirable; even if identity and access management functions are not centralized, this is still generally undesirable in the enterprise.

This authorization grant supports refresh tokens.

Use Case: authentication of end users and access by client to a resource (possibly owned by the end user)

Used By: any client that has access to the end user’s credentials, handles its own login workflow, and (because either you do not care or have no choice) is allowed to perform these tasks.

Additional Uses: Some sources recommend using this grant with your own native apps (rather than the authorization code grant with public client) since full access and control over the source code is ensured. In larger organizations, this may not be a viable assumption. Personally, I would use the authorization code grant with public client as described earlier in this article.

This grant can also be used in place of the Client Credential Grant in situations where a service account is used to represent the system or calling application. A larger strategy surrounding how applications will be represented within the identity stack is recommended before going down this path. Most modern identity providers (those that support OAuth2 and OIDC) will have functionality to represent an application similar to how traditional identity providers can represent a user.

OAuth2 — Client Credential Grant

OAuth2 Client Credential Grant

This grant is different from the other three defined by the OAuth2 spec in that it provides for authenticating the application (or system) only, not an end user.

Refresh tokens are supported with this grant.

Use Case: application or system identity being authenticated and then accessing a resource on a resource server.

Used By: Anything that can keep the client secret confidential, has no need for end user authentication, and needs to access a third-party resource.

OpenID Connect Spec

Information about the OIDC Spec can be found here (earlier in the SAML2 vs. JWT series).

OIDC — Authorization Code Flow

OpenID Connect Authorization Code Flow

This is the first of three OIDC authentication flows. The mechanics of this authentication flow is explored here.

Used By: All commentary made above regarding the OAuth2 Authorization Code Grant applies here. The details won’t be repeated here.

OIDC — Implicit Flow

OpenID Connect Implicit Flow #1
OpenID Connect Implicit Flow #2

The mechanics of this authentication flow are explored here.

Used By: All commentary made above regarding the OAuth2 Implicit Grant applies here. In addition, there is a choice of whether or not an access token is requested to access a backend resource (response_type of “id_token” or “id_token token). If your requirements include accessing a resource, then use “id_token token”. If end user authentication is the only requirement, “id_token” can be used.

OIDC — Hybrid Flow

The mechanics of this authentication flow are explored here.

As described in the OIDC series, this authentication flow is not used very often in the wild.

Used By: A client that

  • needs a separate token for the front end and back end
  • has bandwidth limitations that make a single call to the OP desirable, but still needs more OIDC functionality than is available in the Implicit Flow.

Additional thoughts:

  • Whenever possible, use OIDC instead of pure OAuth2.
  • For most application developers or architects, this information will be strictly academic or help drive requirements surrounding which IdP can be utilized. The choice of IdP and its resulting capabilities will drive design decisions in the identity space more than anything else. Likewise, most IdP vendors will have already created libraries across the various popular platforms for application development. Thus, eliminating the need for the application developer needing to address these details.
  • If using an IdP’s OAuth2 implementation, it’s a near certainty that proprietary features have been added to the implementation to add reliability, security, and completeness to the solution. The OAuth2 spec by itself does not describe the complete solution.
  • Even with the OIDC spec, the login workflow (including prompting for credentials, submission of the credentials and validation of the credentials) are not explicitly defined. It is possible to use SAML2 Browser Profile, WS-Federation, or another authentication mechanism to authenticate the user or implement a federation relationship (that authenticates the end user).
  • Whenever an end user is being authenticated, try to use an interactive login that serves up the login workflow (this can be done with the OAuth2 Authorization Code Grant, OAuth2 Implicit Grant, OIDC Authorization Code Flow, or OIDC Implicit Flow). This promotes a common look and feel and maintains centralized control over the login process.

Some additional information specific to individual IdP vendors:

Image: Architectural Flow / Kevin Dooley

Leave a Reply

Your email address will not be published. Required fields are marked *