OAuth 2.0 Overview
On this page
What is OAuth 2.0?
The original OAuth 2.0 specification was published in the RFC6749 document in 2012. The core design enables a user to grant restricted access, to their own resources, to third party applications. Using OAuth 2.0, users do not share their credentials with the application, since this could give unrestricted access to all the user's resources.
There are four main parties involved in the OAuth core design:
Resource Owner: The entity granting access to resources, which is often an end-user.
Resource Server: The entity hosting the protected resources, which is often a backend API. The resource server receives and validates an access token when processing requests for resources.
Client: The application that needs to access resources on behalf of the resource owner. It does so by sending an access token to the resource server.
Authorization Server: The entity that authenticates the resource owner, then issues access tokens to the client.
OAuth 2.0 terminologies may differ slightly from your everyday terms for these components. In many scenarios, you can replace
resource owner with
resource server with API.
Principles of OAuth 2.0
OAuth 2.0 is an authorization protocol designed to enable clients to access resources on behalf of the resource owner. The client receives an access token, which contains or references rules about the type of access allowed. An access token restricts which data or operations a client can use, and this access can be customized in many ways.
OAuth 2.0 is not an authentication protocol, meaning the RFC6749 specification does not define how authentication works. In reality, authentication is used in every OAuth 2.0 solution. Authorization servers enable users to authenticate in many ways, with one or more proofs of their identity.
Clients do not receive information about the user identity, unless OAuth 2.0 is combined with OpenID Connect. Access tokens are designed for the resource server, and clients should not attempt to read access tokens to obtain the user's identity.
How Does OAuth 2.0 Work?
An abstract OAuth 2.0 flow is represented below, where the resource owner provides a grant to the client. Next, the client uses the grant to get an access token. Finally, the client can send the access token to a resource server and work with protected resources on the user's behalf until the access token expires.
OAuth 2.0 is designed as a general security framework to provide solutions for many use cases. In some of these scenarios, no user is present. In others, clients are not third-party applications, and consent is not required. It is common for clients and resource servers to be developed by the same organization.
Flows and Grant Types
Before an authorization server accepts requests from a client, the client must be registered at the authorization server. This creates a
client_id and sets various other properties, including allowed authentication methods and access token lifetimes. Exact registration details vary depending on the OAuth flow the client intends to use. The following sections summarize some OAuth 2.0 flows.
Authorization Code Flow
The OAuth code flow was originally designed for websites, and involves all four parties. It is a two-step flow, beginning when the client forms an authorization request URL and opens it in the system browser. The resource owner then authenticates at the authorization server, so the client never sees the user credentials.
As a result of the grant, an authorization code is returned to the client in a browser response. This is sent back to the authorization server in an HTTP POST back-channel request, and an access token is returned. This two-step process avoids revealing tokens directly to the browser history or server logs.
The client's authorization request includes scopes, which the authorization server issues in access tokens, along with claims, which provide finer-grained access. The resource server uses scopes and claims later on to authorize requests for protected resources.
The RFC6749 standard also specified the OAuth implicit flow, designed in 2012 for single page applications (SPA). At this time, most browsers did not support cross-origin resource sharing (CORS), preventing SPA clients from being able to send authorization code grant requests. The implicit flow allows the second request in the authorization code flow to be bypassed. An access token is therefore returned directly to the browser in the authorization response.
Client Credentials Flow
In some use cases, a backend process, such as a batch job, must retrieve an access token to call APIs. In such scenarios, the OAuth client credentials flow is used. This flow does not support user authentication and does not require a browser. Only a simple HTTP POST is needed to send a client credentials grant request.
The above sections summarized a few of the original OAuth 2.0 flows, including the code flow, the implicit flow and the client credentials flow. However, many other OAuth 2.0 flows have been introduced since the original RFC6749 specification. These are used to meet additional use cases or to strengthen security further.
Once an OAuth flow completes, the granted authorization (or delegated access) is represented by an access token that the authorization server issues to the client. RFC6749 does not define the format of access tokens. However, authorization servers usually issue access tokens in the JSON Web Token (JWT) format, which are later received by resource servers.
Although the authorization server can return a JWT access token directly to the client, a more secure option is for the authorization server to store the JWT in its backend and return an opaque access token to the client. The client's access token is then a reference to the JWT access token. Issuing tokens in this way avoids revealing sensitive resource server information to the client.
The client then sends its access token, in the HTTP authorization header, when making requests to resource servers. This is typically done multiple times, as the resource owner interacts with the client, until the access token expires.
When an opaque access token is received in the backend, it undergoes OAuth 2.0 token introspection. This enables the full JWT details to be retrieved from the authorization server, then forwarded to the resource server.
The JWT access token consists of a header, payload and signature. Resource servers follow best practices to cryptographically verify the JWT signature. After which, the scopes and claims in the payload can be trusted, and used to implement the resource server's business authorization.
A client can be configured to receive a refresh token and an access token. In this case, you can configure different lifetimes. Keep the access token short-lived, with an expiration such as 15 minutes. The refresh token can have a longer lifetime, such as 4 hours. When required, the client can then send an OAuth 2.0 token refresh request to silently renew an access token without needing to ask the resource owner.
In the event of a stolen access or refresh token, you can use OAuth 2.0 token revocation to prevent a malicious party from using the token. Revocation informs the authorization server that it should no longer accept the token, even if it is unexpired. A common practice is to keep access tokens short-lived, so that if one is stolen, it cannot be exploited for long. Revocation then only needs to be considered for refresh tokens.
Benefits of OAuth 2.0
OAuth 2.0 externalizes the difficult security plumbing from your clients and resource servers. Developers only need to write a small amount of code and do not need to be security experts. Many changes to security behavior can then be controlled solely by configuration changes at the authorization server.
For clients, you can use the authorization server to implement sophisticated multi-factor authentication (MFA), or enable passwordless logins for some or all of your users. You can design authentication according to your own requirements and no longer have to implement difficult security details.
OAuth 2.0 specifications provide a very clean separation of concerns between client and resource server responsibilities. For your backend platform, OAuth 2.0 is a key ingredient in a modern zero-trust architecture for microservices. With this foundation, future security use cases will also become easier to implement.
For these reasons, OAuth 2.0 has become the mainstream security framework for modern digital services, regardless of whether third-party applications are used. In this model, you focus on building your apps, while your authorization server provider continually adds support for new standards.
OAuth 2.0 Best Practices
OAuth 2.0 is a framework, and it is possible to misapply it with suboptimal security. Some of the original flows, such as the implicit flow, are no longer recommended. Your clients must use secure OAuth parameters, and your APIs must make the right checks when access tokens are received. Doing so is necessary to correctly address OAuth threats. Some newer specifications that you should consider using alongside OAuth 2.0 are summarized below:
|OpenID Connect Core||An identity layer on top of OAuth 2.0, providing additional behaviors for clients and resource servers|
|OAuth 2.1||Updated best practices, and areas of the original OAuth 2.0 specification that should no longer be used|
|FAPI 2.0 Security Profile||A stronger OAuth 2.0 security profile that is especially relevant when protecting high worth data|
These days, web and mobile clients should use the OpenID Connect code flow by including the
openid scope. The client can then send extra request parameters to control authentication behavior and receive an ID token after user login, containing user authentication details. A user info endpoint is also provided, for retrieving the personal details of authenticated users. Clients should also implement Proof Key for Code Exchange (PKCE), which proves that the sender of the authorization code grant is the same party who sent the authorization request.
For best protection against exploits, staying up to date with current best practices is recommended. See also the following Curity guidance for client and resource server developers:
- API Security Best Practices
- JWT Best Practices
- Single Page Application Best Practices
- Mobile App Best Practices
Get Started with OAuth 2.0
To get started with OAuth 2.0, you must introduce some new components into your backend platform. This should include an authorization server and an API gateway, both of which must have good extensibility features. The Identity and Access Management Primer can be followed to understand the main steps.
Use respected security libraries in your clients and resource servers. These will deal with the OAuth 2.0 message details for you, with very little code. For information on integrating them, see the Curity guides for web clients, mobile clients, and resource servers. The guides include OAuth 2.0 code examples that can be run from a development computer.
At a software level, the original OAuth 2.0 specification focused on separating the client, resource server and authorization server responsibilities while also putting the user in control. The specification has been highly successful, and has become the most mainstream way to secure modern applications. Applying the OAuth 2.0 framework in the best ways requires some separation but should only ever need simple application code.