DEV Community

Bearer Engineering for Bearer

Posted on • Originally published at bearer.sh

Understanding Auth Part 1: What is OAuth 2.0?

(This article originally appeared on Bearer.sh)

In this series of blog posts, we will look at the varieties of OAuth 2.0, how OpenID Connect builds on top of OAuth 2.0 and fills in a few gaps, and the authentication and authorization ecosystem as a whole.

This first article is all about OAuth 2.0, so let's start with the difference between authorization and authentication:

Authorization relates to whether a client application has permission to access a protected resource. Authentication is about proving the owner of the resource is present, and obtaining information about their identity.

We'll try not to get too technical, but if the gory details are what floats your boat then stay tuned for future articles where we dive deeper into the specifics.

What is OAuth?

The OAuth 2.0 Framework is a standard for authorizing a client application to access protected resources.

The Client ID and Client Secret are what identify a client application. Together they are the known as client credentials and can often be found on the API provider's dashboard.

An API may expose many different resources, and many operations targeting those resources. The client can request limited access to the API by specifying a set of scopes during the authorization process. These scopes are specific to a given API.

A blogging API could use scopes such as read_posts, read_comments and create_post. A different blogging platform may prefer less granularity and offer only read and write scopes in its API.

When the client application completes the authorization process, it obtains an access token. This is then sent along with each API call as proof that the application is allowed to access the requested resource.

To limit the security risk of access tokens that are leaked or logged along with API calls, access tokens can expire after a period of time. The client application then has to go through the authorization process again to obtain a new access token.

Grant types

There are multiple flavors of OAuth 2.0 called grant types. Each one uses a different set of steps to obtain the access token, depending on the kind of client application performing the authorization.

Grant types can be broadly split into 2-legged and 3-legged variants. This refers to the number of parties involved in the authentication process.

3-legged grant types

The three-legged grant types are the most common and support delegating access to a protected resource that is owned by a third-party. The three "legs" are the client application, the API that the client wishes to use (subdivided into an authorization server and resource server), and the resource owner (typically an end user of the client application).

3-legged grant type diagram

The three-legged grant types are designed such that the client never obtains access to the resource owner's credentials, or any information about their identity.

Authorization code grant

The authorization code grant type is the most common variant of OAuth 2.0

Use this grant type when:

  • The client application uses a web browser.
  • The client application is confidential. This is typically when the application is running on a server.

The resource owner's web browser performs a series of steps involving both the client application and the API's authorization server. This is sometimes referred to as the OAuth Dance.

Example: You may experience this grant type if you ever log into an application with another service's credentials, like LinkedIn or Google. The application never directly receives your login and password, but instead handles the process by communicating with the third party.

During this process, the resource owner authenticates directly with the authorization server and a short-lived code is returned to the client application. The client application then authenticates with the authorization server using the client credentials and exchanges the code for the access token.

Although OAuth 2.0 doesn't specify the mechanism of authentication that the authorization server will use, this usually follows a pattern where the user provides their login credentials and then consents to the requested set of scopes.

Implicit grant (not recommended)

Use this grant type when:

  • The client application uses a web browser.
  • The client application is public, e.g., when the application is running entirely within the browser, or when it's a mobile application.

This follows a similar process to the authorization code grant type but returns the access token directly to the client application via the browser, rather than using an intermediate code.

It is not recommended to use the implicit grant type as it is not as secure as other methods. One alternative is to use the Authorization Code grant type with the Proof Key for Code Exchange (PKCE) extension.

Device code grant

The device code grant type is an addition to the original OAuth 2.0 specification.

Use this grant type when:

  • The client application is not using a web browser, or lacks the ability for the user to input their credentials during the authorization flow.
  • The user has access to a web browser with sufficient input capabilities via other means, e.g., via a secondary device.

The client application makes an initial request to the authorization server and obtains a code and verification URL. The resource owner must then manually visit the URL, go through an authentication process, and enter the code. During this process, the client application polls the authorization server. When the process is completed, the access token is returned to the client application.

Example: You may have experienced this grant type when logging into a streaming service on a smart TV. The app gives you a web address and a code to enter, then you log into the service on your phone or computer. Once you enter the provided code, the app on your TV receives the access token and you can begin using the app.

2-legged grant types

The two-legged grant types involve the client application directly supplying the credentials to authorize. The two "legs" are the client application (which might also be the resource owner) and the API that the client application wishes to use (subdivided into an authorization server and resource server).

2-legged grant type diagram

The two-legged grant types are typically used for machine-to-machine (M2M) authorization.

Client credentials grant

Use this grant type when:

  • The client application is accessing its own resources, or permission to access resources has been granted by the resource owner via another (non-OAuth 2.0) mechanism.

Using this grant type, the client application is able to obtain an access token using only its own client credentials (Client ID and Client Secret).

Resource owner password grant (not recommended)

Use this grant type when:

  • The client application is not the resource owner.
  • There is a high degree of trust between the resource owner and the client application.
  • A three-legged grant type cannot be used.

The resource owner provides the client application with a username and password and the client application uses these along with its own client credentials to obtain an access token from the authorization server.

It is not recommended to use the resource owner password grant type as it requires the resource owner to share their credentials with the client application

Refresh token grant

Use this grant type when:

  • A refresh token was returned from a previous authorization request.
  • The access token from a previous authorization request has expired.

When an access token has expired, the client application has to go through the authorization process again to obtain a new access token. For the 3-legged grant types, this would require the user to be present and to re-authenticate. For the 2-legged password grant, this would require the client application to store the user's credentials. This may not always be possible or desirable. To avoid this, many APIs return a refresh token along with the access token which can be used to re-authorize the client application.

Some APIs require refresh tokens to be enabled in their developer dashboard, or only return a refresh token if a special scope (e.g., offline_access) is requested when authorizing.

Using a separate refresh token to periodically renew the access token is more secure than having a long-lived/non-expiring access token. The access token is sent with every request for a protected resource and might be used in many places in the client application. Whereas the refresh token is only sent to the authorization server and its usage in the client application can be far more isolated. This makes it easier to secure the refresh token against being leaked and limits the window of opportunity if the access token were to be leaked.

Token introspection

The OAuth 2.0 specification defines a limited set of metadata (e.g., the access token expiry time and the granted scopes) that can be returned as part of the authorization process. There are other useful pieces of information that have historically been added as non-standard attributes in the authorization response, such as the refresh token expiry time. It's also possible that the information returned at authorization time may become outdated. For example, an access token could be revoked by the resource owner.

The OAuth 2.0 Token Introspectionstandard allows a client application to inspect an access token or refresh token at any time and retrieve up-to-date metadata about it. Some notable values that can be returned are:

  • Whether the token is still active.
  • The scopes that were granted.
  • When the token was issued.
  • When the token expires.
  • Who the resource owner is.

Example: For the Salesforce API, the expiry time of an access token depends on factors that cannot be known at the time of authorization, e.g., when the last API call was made. The token introspection endpoint can be used to check whether the token is still active and when it is currently expected to expire.

Conclusion

In the first part of this series, we looked at OAuth 2.0 and how it standardizes a wide range of authorization scenarios that are relevant to building and consuming APIs. Although there is still a lot of complexity in the details of OAuth 2.0, having a standard allows libraries, frameworks and services to help you manage this so you can keep your users' data secure and focus on the core business logic of your application.

Don't miss the next part in this series where we look at OpenID Connect and how it can be used to support "Sign in with Google" type functionality, and more! 🚀

Discuss this article on Twitter and ping us @BearerSH.

Top comments (0)