Konubinix' opinionated web of thoughts

OAuth 2.0

Fleeting

OAuth stands for open authorization. There are a lot of specifications made by OAuth guys, but when people talk about OAuth2, they generally mean the initial specification created in 2012: OAuth 2.0 authorization framework (a.k.a. RFC 6749). This RFC defines the authorization delegation flows and defines the four roles (a client that gets granted access by an authorization server of resources belonging to a resource owner and stored in a resource server) and concepts (bearer token, access token, refresh token, etc).

It seems like OAuth2 guys also invented JWT (a.k.a. RFC 7519).

It also seems like a lot of implementations have made use of JWT (and more precisely JWS and JWE compact serialisations) to encode the access token in a self-encoded access tokens.

Now, people tend to forget that the framework was defined with opaque bearer token in mind and that using a JWT encoded access token is not part of the initial spec.

This use of JWT everywhere appears to be the reason why OAuth guys came with another RFC to try to specify a bit what should be put in those self-encoded access tokens. This RFC, called JWT Access Tokens for OAuth 2.0 (a.k.a. RFC9068) is very young (October 2021) compared to the initial spec (October 2012). They even suggest this in their website.1

Also, people also tend to forget that OAuth is only about authorization and not at all about authentication. Authentication is needed prior to authorize anything, but OAuth does not say a thing about it. That is one of the reasons why OpenID Connect exists. It is an extension that brings (among other things) this missing piece: authentication. Because this is strongly related to the notion of identity, it adds the concept of Identity Token (which is actually specified to be JWT encoded, making people confuse it with a self-encoded access tokens). It also defined a few oauth 2.0 scopes related to user’s identity (like openid).

In contrast to OAuth 2.0 access token, which is supposed to be opaque from the client point of view, the ID Token is meant to be read by this role. See ID Tokens vs Access Tokens.

Nothing is said in OAuth about how the resource server and the client should link resources to self-encoded access tokens claims.

The classical flow of OAuth 2.0 ensures that the client and resource servers won’t ever see the users credentials.2

The other flows are tailored to specific use cases and try to make sensible compromises on security.

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service

https://datatracker.ietf.org/doc/html/rfc6749

OAuth defines four roles:

resource owner
An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user.
resource server
The server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens.
client
An application making protected resource requests on behalf of the resource owner and with its authorization. The term “client” does not imply any particular implementation characteristics (e.g., whether the application executes on a server, a desktop, or other devices).
authorization server
The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization.

https://datatracker.ietf.org/doc/html/rfc6749#section-1.1

  • (A) The client requests authorization from the resource owner. The authorization request can be made directly to the resource owner (as shown), or preferably indirectly via the authorization server as an intermediary.

  • (B) The client receives an authorization grant, which is a credential representing the resource owner’s authorization, expressed using one of four grant types defined in this specification or using an extension grant type. The authorization grant type depends on the method used by the client to request authorization and the types supported by the authorization server.

  • (C) The client requests an access token by authenticating with the authorization server and presenting the authorization grant.

  • (D) The authorization server authenticates the client and validates the authorization grant, and if valid, issues an access token.

  • (E) The client requests the protected resource from the resource server and authenticates by presenting the access token.

  • (F) The resource server validates the access token, and if valid, serves the request.

https://datatracker.ietf.org/doc/html/rfc6749

OAuth defines two client types, based on their ability to authenticate securely with the authorization server (i.e., ability to maintain the confidentiality of their client credentials):

confidential Clients capable of maintaining the confidentiality of their credentials (e.g., client implemented on a secure server with restricted access to the client credentials), or capable of secure client authentication using other means.

public Clients incapable of maintaining the confidentiality of their credentials (e.g., clients executing on the device used by the resource owner, such as an installed native application or a web browser-based application), and incapable of secure client authentication via any other means.

https://datatracker.ietf.org/doc/html/rfc6749

web application
A web application is a confidential client running on a web server. Resource owners access the client via an HTML user interface rendered in a user-agent on the device used by the resource owner. The client credentials as well as any access token issued to the client are stored on the web server and are not exposed to or accessible by the resource owner.
user-agent-based application
A user-agent-based application is a public client in which the client code is downloaded from a web server and executes within a user-agent (e.g., web browser) on the device used by the resource owner. Protocol data and credentials are easily accessible (and often visible) to the resource owner. Since such applications reside within the user-agent, they can make seamless use of the user-agent capabilities when requesting authorization.
native application
A native application is a public client installed and executed on the device used by the resource owner. Protocol data and credentials are accessible to the resource owner. It is assumed that any client authentication credentials included in the application can be extracted. On the other hand, dynamically issued credentials such as access tokens or refresh tokens can receive an acceptable level of protection. At a minimum, these credentials are protected from hostile servers with which the application may interact. On some platforms, these credentials might be protected from other applications residing on the same device.

https://datatracker.ietf.org/doc/html/rfc6749

The authorization server issues the registered client a client identifier – a unique string representing the registration information provided by the client. The client identifier is not a secret; it is exposed to the resource owner and MUST NOT be used alone for client authentication. The client identifier is unique to the authorization server.

https://datatracker.ietf.org/doc/html/rfc6749

The token may denote an identifier used to retrieve the authorization information or may self-contain the authorization information in a verifiable manner (i.e., a token string consisting of some data and a signature). Additional authentication credentials, which are beyond the scope of this specification, may be required in order for the client to use a token

https://datatracker.ietf.org/doc/html/rfc6749

This specification makes extensive use of HTTP redirections, in which the client or the authorization server directs the resource owner’s user-agent to another destination.

https://datatracker.ietf.org/doc/html/rfc6749

This specification defines four grant types:

  1. authorization code,
  2. implicit,
  3. resource owner password credentials,
  4. and client credentials

https://datatracker.ietf.org/doc/html/rfc6749

An authorization grant is a credential representing the resource owner’s authorization (to access its protected resources) used by the client to obtain an access token

https://datatracker.ietf.org/doc/html/rfc6749

The resource owner password credentials (i.e., username and password) can be used directly as an authorization grant to obtain an access token.

https://datatracker.ietf.org/doc/html/rfc6749

The credentials should only be used when there is a high degree of trust between the resource owner and the client (e.g., the client is part of the device operating system or a highly privileged application), and when other authorization grant types are not available (such as an authorization code)

https://datatracker.ietf.org/doc/html/rfc6749

This grant type can eliminate the need for the client to store the resource owner credentials for future use, by exchanging the credentials with a long-lived access token or refresh token.

https://datatracker.ietf.org/doc/html/rfc6749

The client credentials (or other forms of client authentication) can be used as an authorization grant when the authorization scope is limited to the protected resources under the control of the client

https://datatracker.ietf.org/doc/html/rfc6749

When choosing between the implicit grant type and the authorization code grant type, the following should be considered:

o Native applications that use the authorization code grant type SHOULD do so without using client credentials, due to the native application’s inability to keep client credentials confidential.

o When using the implicit grant type flow, a refresh token is not returned, which requires repeating the authorization process once the access token expires.

https://datatracker.ietf.org/doc/html/rfc6749

Authorization codes operate as plaintext bearer credentials, used to verify that the resource owner who granted authorization at the authorization server is the same resource owner returning to the client to complete the process.

https://datatracker.ietf.org/doc/html/rfc6749

Authorization codes MUST be short lived and single-use.

https://datatracker.ietf.org/doc/html/rfc6749

Unlike access tokens, refresh tokens are intended for use only with authorization servers and are never sent to resource servers.

https://datatracker.ietf.org/doc/html/rfc6749

  • (A) The client requests an access token by authenticating with the authorization server and presenting an authorization grant.

  • (B) The authorization server authenticates the client and validates the authorization grant, and if valid, issues an access token and a refresh token.

  • (C) The client makes a protected resource request to the resource server by presenting the access token.

  • (D) The resource server validates the access token, and if valid, serves the request.

  • (E) Steps (C) and (D) repeat until the access token expires. If the client knows the access token expired, it skips to step (G); otherwise, it makes another protected resource request.

  • (F) Since the access token is invalid, the resource server returns an invalid token error.

  • (G) The client requests a new access token by authenticating with the authorization server and presenting the refresh token. The client authentication requirements are based on the client type and on the authorization server policies.

  • (H) The authorization server authenticates the client and validates the refresh token, and if valid, issues a new access token (and, optionally, a new refresh token).

Steps (C), (D), (E), and (F) are outside the scope of this specification, as described in Section 7.

https://datatracker.ietf.org/doc/html/rfc6749

This specification does not provide any methods for the resource server to ensure that an access token presented to it by a given client was issued to that client by the authorization server

https://datatracker.ietf.org/doc/html/rfc6749#section-10.3

ability to send request parameters in a JSON Web Token (JWT) instead, which allows the request to be signed with JSON Web Signature (JWS) and encrypted with JSON Web Encryption (JWE) so that the integrity, source authentication, and confidentiality properties of the authorization request are attained. The request can be sent by value or by reference

https://datatracker.ietf.org/doc/html/rfc9101

This specification defines the use of a JSON Web Token (JWT) Bearer Token as a means for requesting an OAuth 2.0 access token as well as for client authentication.

https://datatracker.ietf.org/doc/html/rfc7523

what is not OAuth 2.0 is not useless or a bad idea

It’s just not supported by a group of people that have spent more than 10 years trying to define something secure.

For instance, you might have a good flow based on the implicit grant. It’s just not oauth anymore.

For example, OpenID Connect provide something very similar to the implicit grant, with a way to validate the access token using its hash in the id token.

the purpose of OAuth 2.0 was to avoid that the client oauth 2.0 sees the resource owner’s password

user consent screen

It is the human readable version of the oauth 2.0 scope, so that the resource owner can give per consent.

it starts with a oauth 2.0 client registering itself with a authorization server

user agent

Generally the web browser. The stuff used by the user to perform the authentication and used, via http redirection to share the authorization code.

two modes of communication

an ambiguity

There were defined at a time (~2010) when only backend could make secure connections. Therefore we need to remember that front channel actually means with intermediary, insecure and back channel means end-to-end and encrypted.

A front end can totally make back channel communication as of today.

front channel is about UI and the back channel is about converting the outcome of the frontchannel to tokens

The front channel is insecure and not trustworthy to send data between the authorization server and the oauth 2.0 client. Yet it is the only way so far to make the resource owner be part of this triangle communication and give per consent

back channel

A secure (meaning https) end to end communication.

For instance, it is the way the authorization code is shared between the authorization server and the oauth 2.0 client.

front channel

A less secure way of sharing information than the back channel, where the user agent is involved to share some information, like a mailman between two parties.

For instance, the authorization code is issued by the authorization server to the oauth 2.0 client using a 302 response.

The user agent being a man in the middle, there is no way for the authorization server to find out whether the oauth 2.0 client actually correctly received appropriate data and for the oauth 2.0 client to find out whether the data got from the authorization server is the correct one.

Also, there is no certainty that the data in the url did not got spoofed and used by the spoofer. Therefore, the implicit grant, with all the extensions like the browser syncing ones that save and reuse the browser history, is not deprecated.

Fortunately, the authorization code grant with PKCE mitigates this issue.

metaphor of the wall

It is like the frontchannel is a wall and you send stuff to the other side.

You cannot tell whether someoen got it and whether this someone is actually the appropriate recipient.

Also, the recipient cannot tell whether the stuff that is thrown above the wall comes from the appropriate sender.

cross jwt confusion

  • External reference: https://datatracker.ietf.org/doc/html/rfc8725#section-3.9

    As JWTs are being used by more different protocols in diverse application areas, it becomes increasingly important to prevent cases of JWT tokens that have been issued for one purpose being subverted and used for another. Note that this is a specific type of substitution attack. If the JWT could be used in an application context in which it could be confused with other kinds of JWTs, then mitigations MUST be employed to prevent these substitution attacks.

    https://datatracker.ietf.org/doc/html/rfc8725#section-2.8

    the JWT MUST contain an “aud” (audience) claim that can be used to determine whether the JWT is being used by an intended party or was substituted by an attacker at an unintended party.

    In such cases, the relying party or application MUST validate the audience value, and if the audience value is not present or not associated with the recipient, it MUST reject the JWT.

    https://datatracker.ietf.org/doc/html/rfc8725#section-3.9

To prevent substitution of JWTs from one context into another, application developers may employ a number of strategies:

  • Use explicit typing for different kinds of JWTs. Then the distinct “typ” values can be used to differentiate between the different kinds of JWTs.
  • Use different sets of required claims or different required claim values. Then the validation rules for one kind of JWT will reject those with different claims or values.
  • Use different sets of required Header Parameters or different required Header Parameter values. Then the validation rules for one kind of JWT will reject those with different Header Parameters or values.
  • Use different keys for different kinds of JWTs. Then the keys used to validate one kind of JWT will fail to validate other kinds of JWTs.
  • Use different “aud” values for different uses of JWTs from the same issuer. Then audience validation will reject JWTs substituted into inappropriate contexts.
  • Use different issuers for different kinds of JWTs. Then the distinct “iss” values can be used to segregate the different kinds of JWTs.

Given the broad diversity of JWT usage and applications, the best combination of types, required claims, values, Header Parameters, key usages, and issuers to differentiate among different kinds of JWTs will, in general, be application-specific.

https://datatracker.ietf.org/doc/html/rfc8725#section-3.12

5 types of grant -> now only 2

authorization code grant

The client constructs the request URI by adding the following parameters to the query component of the authorization endpoint URI using the “application/x-www-form-urlencoded” format, per Appendix B:

response_type
REQUIRED. Value MUST be set to “code”.
client_id
REQUIRED. The client identifier as described in Section 2.2.
redirect_uri
OPTIONAL. As described in Section 3.1.2.
scope
OPTIONAL. The scope of the access request as described by Section 3.3
state
RECOMMENDED. An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. The parameter SHOULD be used for preventing cross-site request forgery as described in Section 10.12.

https://datatracker.ietf.org/doc/html/rfc6749#section-4.1

Authorization Code Flow returns an Authorization Code to the Client, which can then exchange it for an ID Token and an Access Token directly. This provides the benefit of not exposing any tokens to the User Agent and possibly other malicious applications with access to the User Agent

https://openid.net/specs/openid-connect-core-1_0.html#Introduction

authorization code

password grant

implicit grant

  • External reference: https://datatracker.ietf.org/doc/html/rfc6749#section-4.2

    Authorization Request

    The client constructs the request URI by adding the following parameters to the query component of the authorization endpoint URI using the “application/x-www-form-urlencoded” format, per Appendix B:

    response_type
    REQUIRED. Value MUST be set to “token”.
    client_id
    REQUIRED. The client identifier as described in Section 2.2.
    redirect_uri
    OPTIONAL. As described in Section 3.1.2.
    scope
    OPTIONAL. The scope of the access request as described by Section 3.3
    state
    RECOMMENDED. An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. The parameter SHOULD be used for preventing cross-site request forgery as described in Section 10.12.

    https://datatracker.ietf.org/doc/html/rfc6749#section-4.2

What is an Access Token?

Access tokens do not have to be in any particular format, and in practice, various OAuth servers have chosen many different formats for their access tokens

https://oauth.net/2/access-tokens/

Access tokens may be either “bearer tokens” or “sender-constrained” tokens. Sender-constrained tokens require the OAuth client to prove possession of a private key in some way in order to use the access token, such that the access token by itself would not be usable

https://oauth.net/2/access-tokens/

Access tokens must not be read or interpreted by the OAuth client. The OAuth client is not the intended audience of the token.

https://oauth.net/2/access-tokens/

Access tokens should only be used to make requests to the resource server

https://oauth.net/2/access-tokens/

authorization server

authorization request

Rich Authorization Requests

JWT-Secured Authorization Request

Pushed Authorization Requests

the resource owner needs to know the authorization server and trust it

This is the entity that will gets the user password and provide the user consent screen. A trust relationship between those entities is needed.

resource server

refresh token

https://datatracker.ietf.org/doc/html/rfc6749

Unlike access tokens, refresh tokens are intended for use only with authorization servers and are never sent to resource servers.

https://datatracker.ietf.org/doc/html/rfc6749

used to obtain a new access token when the current access token becomes invalid or expires, or to obtain additional access tokens with identical or narrower scope

https://datatracker.ietf.org/doc/html/rfc6749

Refresh tokens are credentials used to obtain access tokens.

https://datatracker.ietf.org/doc/html/rfc6749

refresh token rotation

According to OAuth – the good Parts - Anders Abel - NDC Oslo 2022, refresh tokens should be chained. Each refresh token should be for one time use only and refreshing should issue another refresh token. That way, when you don’t manage to refresh, you know someone spoofed it and can invalidate all the tokens made by this chain.

According to Forget about OAuth 2.0. Here comes OAuth 2.1 - Philippe De Ryck - NDC Oslo 2022, this does not prevent attacks. When an attacker gets access to the client code (using XSS), per can make the application ping a remote server to make it know how long the client session is open.

When the remote server ceases to receive pings, it can simply use the last refresh token. Per won’t be bothered as long as the user keeps logged out.

See also OIDC Silent Authentication.

Auth0 recommends using refresh token rotation which provides a secure method for using refresh tokens in SPAs while providing end-users with seamless access to resources without the disruption in UX caused by browser privacy technology like ITP.

https://auth0.com/docs/secure/tokens/refresh-tokens

technique for getting new access tokens using refresh tokens that goes beyond silent authentication.

https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation

Refresh tokens are often used in native applications on mobile devices in conjunction with short-lived access tokens to provide seamless UX without having to issue long-lived access tokens.

https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation

Until very recently, SPAs maintained the user’s session by using the Authorization Code Flow with PKCE in conjunction with silent authentication

https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation

Unfortunately, long-lived refresh tokens are not suitable for SPAs because there is no persistent storage mechanism in a browser that can assure access by the intended application only

https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation

using refresh tokens in SPAs has been strongly discouraged.

https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation

Refresh token rotation offers a remediation to end-user sessions being lost due to side-effects of browser privacy mechanisms. Because refresh token rotation does not rely on access to the Auth0 session cookie, it is not affected by ITP or similar mechanisms.

https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation

As soon as the new pair is issued by Auth0, the refresh token used in the request is invalidated. This safeguards your app from replay attacks resulting from compromised tokens.

https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation

access token

The access token provides an abstraction layer, replacing different authorization constructs (e.g., username and password) with a single token understood by the resource server. This abstraction enables issuing access tokens more restrictive than the authorization grant used to obtain them, as well as removing the resource server’s need to understand a wide range of authentication methods.

https://datatracker.ietf.org/doc/html/rfc6749

access token is a string representing an authorization issued to the client. The string is usually opaque to the client

https://datatracker.ietf.org/doc/html/rfc6749

It may be a bearer token, provided in the authorization header as defined in https://datatracker.ietf.org/doc/html/rfc2617.

use different lifetimes for your access tokens depending on the criticality of the scope

short lived

token instrospection

kinds of token

reference token vs self-encoded access token

reference token self encoded access token
easy to invalidate needs to wait token expiration
needs more authorization server calls only need to fetch the public key from time to time
not easily confused with id token clients tend to feel legitimate looking into it
needs to implement introspection in the resource server easier dev because the token contains all the needed information

This looks like a simple comparison, but depending on the properties of the self-encoded access token, the comparison might less relevant. For instance, the less the expiration time, the more the self encoded access token resembles a reference token with regards to validity and authorization call load.

Also, using JWE, one can make the token more opaque and mitigate the issue with client looking where they should not.

use an API Gateway

The API Gateway can, depending on the accessed data, decide to let the self-encoded access token go through or perform a token instrospection lookup to avoid the possibility of false positive (security vs user experience balance).

Is also provide a fast filter, allowing the domain logic to perform the slower checks in fewer requests.

reference token

A token that does not contain useful information and needs to go through a token instrospection endpoint, as opposed to a self-encoded access token.

self-encoded access tokens

API servers are able to verify access tokens without doing a database lookup on every API request, making the API much more easily scalable

https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/

benefit of OAuth 2.0 Bearer Tokens is that applications don’t need to be aware of how you’ve decided to implement access tokens in your service. This means it’s possible to change your implementation later without affecting clients.

https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/

using self-encoded tokens if you’ve already solved the distributed database problem will only introduce new issues, as invalidating self-encoded tokens becomes an additional hurdle

https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/

One way to create self-encoded tokens is to create a JSON-serialized representation of all the data you want to include in the token, and sign the resulting string with a key known only to your server.

https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/

bearer token

When sending the access token in the “Authorization” request header field defined by HTTP/1.1 [RFC2617], the client uses the “Bearer” authentication scheme to transmit the access token.

For example:

GET /resource HTTP/1.1 Host: server.example.com Authorization: Bearer mF_9.B5f-4.1JqM

https://datatracker.ietf.org/doc/html/rfc6750

oauth 2.0 client

application area in which JWTs are commonly used is representing digital identity information, such as OpenID Connect ID Tokens [OpenID.Core] and OAuth 2.0 [RFC6749] access tokens and refresh tokens, the details of which are deployment-specific

https://datatracker.ietf.org/doc/html/rfc8725

authorization request in OAuth 2.0 described in RFC 6749 utilizes query parameter serialization

https://datatracker.ietf.org/doc/html/rfc9101

This document introduces the ability to send request parameters in a JSON Web Token (JWT) instead

https://datatracker.ietf.org/doc/html/rfc9101

allows the request to be signed with JSON Web Signature (JWS) and encrypted with JSON Web Encryption (JWE) so that the integrity, source authentication, and confidentiality properties of the authorization request are attained

https://datatracker.ietf.org/doc/html/rfc9101

The most common way to implement self-encoded tokens is to use the JWS spec, creating a JSON-serialized representation of all the data you want to include in the token, and signing the resulting string with a private key known only to your authorization server.

https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/

RFC 9068 defines a standard way to use JWTs as access tokens, based on the real-world deployment experience of a number of large OAuth providers.

https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/

Because the token can be verified without doing a database lookup, there is no way to invalidate a token until it expires

https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/

need to make some decisions as to how long you want the tokens to last. Unfortunately there is no blanket solution for every service

https://www.oauth.com/oauth2-servers/access-tokens/access-token-lifetime/

common method of granting tokens is to use a combination of access tokens and refresh tokens for maximum security and flexibility. The OAuth 2.0 spec recommends this option, and several of the larger implementations have gone with this approach

https://www.oauth.com/oauth2-servers/access-tokens/access-token-lifetime/

OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf. This specification replaces and obsoletes the OAuth 1.0 protocol described in RFC 5849.

https://datatracker.ietf.org/doc/html/rfc6749

JWT access token
An OAuth 2.0 access token encoded in JWT format and complying with the requirements described in this specification

https://datatracker.ietf.org/doc/html/rfc9068

OAuth 2.0, which stands for “Open Authorization”, is a standard designed to allow a website or application to access resources hosted by other web apps on behalf of a user

https://auth0.com/intro-to-iam/what-is-oauth-2/

OAuth 2.0 is an authorization protocol and NOT an authentication protocol

https://auth0.com/intro-to-iam/what-is-oauth-2/

designed primarily as a means of granting access to a set of resources,

https://auth0.com/intro-to-iam/what-is-oauth-2/

Access Token is a piece of data that represents the authorization to access resources on behalf of the end-user.

https://auth0.com/intro-to-iam/what-is-oauth-2/

OAuth 2.0 doesn’t define a specific format for Access Tokens. However, in some contexts, the JSON Web Token (JWT) format is often used. This enables token issuers to include data in the token itself.

https://auth0.com/intro-to-iam/what-is-oauth-2/

for security reasons, Access Tokens may have an expiration date.

https://auth0.com/intro-to-iam/what-is-oauth-2/

Scopes are an important concept in OAuth 2.0. They are used to specify exactly the reason for which access to resources may be granted.

https://auth0.com/intro-to-iam/what-is-oauth-2/

for better security, an Authorization Code may be returned, which is then exchanged for an Access Token.  In

https://auth0.com/intro-to-iam/what-is-oauth-2/

grants are the set of steps a Client has to perform to get resource access authorization

https://auth0.com/intro-to-iam/what-is-oauth-2/

There are three main steps to OAuth 2.0:

  • Request authorization from a user to access their data.
  • Query the user’s data using the provided access token.
  • Refresh expired access tokens with the corresponding refresh token.

https://dev.fitbit.com/build/reference/web-api/developer-guide/authorization/

traditional client-server authentication model, the client requests an access-restricted resource (protected resource) on the server by authenticating with the server using the resource owner’s credentials. In order to provide third-party applications access to restricted resources, the resource owner shares its credentials with the third party.

https://datatracker.ietf.org/doc/html/rfc6749

Third-party applications gain overly broad access to the resource owner’s protected resources, leaving resource owners without any ability to restrict duration or access to a limited subset of resources

https://datatracker.ietf.org/doc/html/rfc6749

o Resource owners cannot revoke access to an individual third party without revoking access to all third parties, and must do so by changing the third party’s password

https://datatracker.ietf.org/doc/html/rfc6749

OAuth addresses these issues by introducing an authorization layer and separating the role of the client from that of the resource owner.

https://datatracker.ietf.org/doc/html/rfc6749

Instead of using the resource owner’s credentials to access protected resources, the client obtains an access token – a string denoting a specific scope, lifetime, and other access attributes. Access tokens are issued to third-party clients by an authorization server with the approval of the resource owner. The client uses the access token to access the protected resources hosted by the resource server.

https://datatracker.ietf.org/doc/html/rfc6749

For example, an end-user (resource owner) can grant a printing service (client) access to her protected photos stored at a photo- sharing service (resource server), without sharing her username and password with the printing service. Instead, she authenticates directly with a server trusted by the photo-sharing service (authorization server), which issues the printing service delegation- specific credentials (access token).

https://datatracker.ietf.org/doc/html/rfc6749

use of OAuth over any protocol other than HTTP is out of scope.

https://datatracker.ietf.org/doc/html/rfc6749

single authorization server may issue access tokens accepted by multiple resource servers.

https://datatracker.ietf.org/doc/html/rfc6749

authorization code is obtained by using an authorization server as an intermediary between the client and resource owner

https://datatracker.ietf.org/doc/html/rfc6749

client directs the resource owner to an authorization server (via its user-agent as defined in [RFC2616]), which in turn directs the resource owner back to the client with the authorization code

https://datatracker.ietf.org/doc/html/rfc6749

Because the resource owner only authenticates with the authorization server, the resource owner’s credentials are never shared with the client.

https://datatracker.ietf.org/doc/html/rfc6749

authorization code provides a few important security benefits, such as the ability to authenticate the client, as well as the transmission of the access token directly to the client without passing it through the resource owner’s user-agent and potentially exposing it to others, including the resource owner

https://datatracker.ietf.org/doc/html/rfc6749

When issuing an access token during the implicit grant flow, the authorization server does not authenticate the client. In some cases, the client identity can be verified via the redirection URI used to deliver the access token to the client. The access token may be exposed to the resource owner or other applications with access to the resource owner’s user-agent.

https://datatracker.ietf.org/doc/html/rfc6749

client credentials (or other forms of client authentication) can be used as an authorization grant when the authorization scope is limited to the protected resources under the control of the client, or to protected resources previously arranged with the authorization server.

https://datatracker.ietf.org/doc/html/rfc6749

when the client is acting on its own behalf (the client is also the resource owner) or is requesting access to protected resources based on an authorization previously arranged with the authorization server.

https://datatracker.ietf.org/doc/html/rfc6749

resource owner password credentials grant type is suitable in cases where the resource owner has a trust relationship with the client,

https://datatracker.ietf.org/doc/html/rfc6749

server should take special care when enabling this grant type and only allow it when other flows are not viable.

https://datatracker.ietf.org/doc/html/rfc6749

suitable for clients capable of obtaining the resource owner’s credentials (username and password, typically using an interactive form).

https://datatracker.ietf.org/doc/html/rfc6749

two kinds of client

public client

In brief, a public client runs on an environment that the END USER controls.

It cannot keep secret the client secret and therefore cannot do the authorization code flow. Yet, it can run the authorization code grant with PKCE, because it is like the former, but with a dynamically generated client secret.

A public client cannot ensure that the client id or client secret are not re-used by the users of the client. In case of web client, one should rather use server side communication with the server hosting the web client to ensure the id of the client.

confidential

In brief, a public client runs on an environment that the DEVELOPER controls.

It can keep secret the client secret and then use the authorization code flow securely.

client id

client secret

Its purpose is to make sure in the end of the flow that the client is indeed the expected one. This makes only sense in the case of a confidential client, because in the case of a public client, the secret can easily be read by anyone using the client.

In the case of a public client, one should rather use authorization code grant with PKCE.

do we really need client_secret to get access_token on PKCE flow?

OAuth 2.0 access token response

authorization server issues an access token and optional refresh token, and constructs the response by adding the following parameters to the entity-body of the HTTP response with a 200 (OK) status code:

https://datatracker.ietf.org/doc/html/rfc6749

access_token
REQUIRED. The access token issued by the authorization server.
token_type
REQUIRED. The type of the token issued as described in Section 7.1. Value is case insensitive.
expires_in
RECOMMENDED. The lifetime in seconds of the access token. For example, the value “3600” denotes that the access token will expire in one hour from the time the response was generated. If omitted, the authorization server SHOULD provide the expiration time via other means or document the default value.
refresh_token
OPTIONAL. The refresh token, which can be used to obtain new access tokens using the same authorization grant as described in Section 6.
scope
OPTIONAL, if identical to the scope requested by the client; otherwise, REQUIRED. The scope of the access token as described by Section 3.3.

https://datatracker.ietf.org/doc/html/rfc6749

For example:

HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache

{ “access_token”:“2YotnFZFEjr1zCsicMWpAA”, “token_type”:“example”, “expires_in”:3600, “refresh_token”:“tGzv3JOkF0XG5Qx2TlKWIA”, “example_parameter”:“example_value” }

https://datatracker.ietf.org/doc/html/rfc6749

Notes linking here


  1. JWTs can be used as OAuth 2.0 Bearer Tokens to encode all relevant parts of an access token into the access token itself instead of having to store them in a database

    https://oauth.net/2/jwt/

     ↩︎
  2. Before directing the resource owner back to the client with the authorization code, the authorization server authenticates the resource owner and obtains authorization. Because the resource owner only authenticates with the authorization server, the resource owner’s credentials are never shared with the client.

    https://datatracker.ietf.org/doc/html/rfc6749

     ↩︎