OAuth 2.0 is an open-standard authorization framework that essentially allows services or servers to provide delegated and regulated access to their assets. Furthermore, OAuth Grant Types allow different kinds of access for various use cases. Picking the right one as per your requirements can be the difference between a robust offering and a mediocre or insecure one. Let’s dive into it.
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
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.
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. 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.
This is how the Proof Key for Code Exchange (PKCE) flow looks:
- The client officially dispatches the authorization request with the code_challenge and also the code_challenge_method
- The Authorization Server registers both the code_challenge and the code_challenge_method. It then issues the authorization code
- An access token request is sent by the client with the code_verifier
- 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
|Implicit Grant Type|
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.
3. 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.
The device authorization flow goes as follows:
- The client authorization server gets a request access from the client, which also includes it’s “client identifier”
- End-user and device codes are issued by the authorization server. The end-user gets a verification URI
- 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
- 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
- The authorization server validates the user code provided by the user, and prompts the user to accept or decline the request
- The authorization server is polled by the client to verify if the user authorization is complete (device code and client identifier are included)
- 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:
4. 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.
5. 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.
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.