1. Introduction
In this tutorial, we’ll discuss the OAuth 2.0 protocol flow. We’ll discuss the basic protocol flow. There are other variations to this flow bases on the different use cases, for example in case of refresh tokens there is an extra step to get the new access token in case the existing access token is expired.
2. Actors in OAuth 2.0
- Resource Owner: Resource is the information or the data that is being accessed. Resource Owner is the owner of this information. If the information is owned by a person, the resource owner is known as the user. A resource owner is the one who owns the information and is capable of granting the access to this information.
- Client: A client is an application that is accessing the information on the user’s behalf. This application can be a mobile application, web application or a simple rest client like Postman. A resource owner is a user who is accessing the client application to access the information on the resource server.
- Resource server: A resource server hosts the user information. It could be a Google server, Facebook server or any other server hosting the information. In case of a microservice architecture, each microservice can be considered as a resource server.
- Authorization server: Authorization server issues access tokens to the client application after successfully authenticating the client application after successfully authenticating the resource owner and obtaining authorization. Companies like Google, Facebook have their own authorization servers. That is why we are allowed to login to our apps using the Google or Facebook accounts. But we can also create our own authorization servers. For example, there are Spring Authorization Server and Keycloak Authorization Server. Other authorization server examples are AWS Cognito, Microsoft Identity Platform and Okta.
3. Client Types
OAuth framework defines two different client types based on their ability to authenticate securely with the authorization server. As discussed earlier, the resource owner access the resource server using the client application. This client application could be a native app on a user device, a secure app running on the server or a single page browser-based application. All these client applications are capable of sending http requests to the authorization server. In order for a client application to connect with authorization server, client application needs to register with the authorization server and get its client Id and client secret key. Client Id and secret key are needed for a client application to communicate with the authorization server securely. Authorization server recognizes the client application using the client Id.
Sometimes, the client application needs to share the secret key while communicating with the authorization server. Not all client applications are capable of securely storing the secret keys. That is why client applications are divided into two different types – Public clients and confidential clients.
Confidential client: Confidential client applications are capable of storing the client secret key safe at their side. Such clients are provided a secret key and can communicate with the authorization server using Client Id and secret key.
Public Client: Public Client can not guarantee the safety of Client Id and secret key at their end. These can be browser based and run entirely in the browser window. For example, a single page JavaScript application. When these type of applications are registered with an authorization server as public client then it is possible that secret key is not assigned at all.
Since there are two client types, OAuth framework defines different authorization flows. Which authorization flow to be used depends on the type of client application connecting with the authorization server.
4. OAuth 2.0 flow
The following diagram shows the typical OAuth 2.0 protocol flow:
The diagram shows the interaction between four roles in OAuth protocol.
(A). The client requests authorization from the resource owner. The authorization request can be made directly to the resource owner, or indirectly via the authorization server as intermediary.
(B). The client receives the authorization grant. Authorization grant is one of four grant types. 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 presents the authorization grant to the authorization server and requests for access token.
(D). The authorization server issues an access token after authenticating client and validating authorization grant.
(E). The client presents the access token to the resource server and requests for the protected resource.
(F). The resource server validates the access token, and if valid, serves the request.
5. Terms related to OAuth 2.0
5.1 Authorization Grant
An authorization grant is authorization by the resource owner to access its protected resources. An authorization grant represents a credential and is used by client to obtain an access token. OAuth specification defines four grant types: authorization code, implicit, resource owner password credentials, and client credentials. OAuth also provides mechanism for defining additional types. The most common OAuth grant types are:
- Authorization Code
- Client Credentials
- Device Code
- Refresh Token
- PKCE
- Implicit Flow (Legacy)
- Password Grant (Legacy)
5.2 Access Token
The token may denote an identifier used to retrieve the authorization information or may self-contain the authorization information in a verifiable information in a verifiable manner(i.e. a token string consisting of some data and a signature). So the access token can be:
- Identifier type
- Self-contain the authorization information
Identifier type access token: When the access token is an identifier type, it is usually an alphanumeric string. The access token is saved in the authorization server’s database and is used later to verify if this is the correct token. The implementation of this access token depends on the authorization server. Since the identifier type access token does not contain any sensitive information, it is being used to look out this information that is associated with this token in a database table.
access_token | user_id | scope | expires |
BYLsjdgYkfhd87Js65 | HwtejYgdj | profile, documents | 16846382973 |
This is a sample table and the actual table can have many more fields.
Self contained access token: The self-contain type of access token is a much longer alphanumeric string and contains the authorization information. This type of access token is a Json object that contains user authorization information and this Json object is Base 64 encoded. You can decode this Base 64 coded JSON using various online tools. One of the online tool is jwt.io So this type of access tokens should not contain sensitive information like user password. For example,
eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImF1ZCI6WyJkZDlVM1FGd05GMlBRZnZsSHpUY1NTdU5DMndhIl0sImF6cCI6ImRkOVUzUUZ3TkYyUFFmdmxIelRjU1N1TkMyd2EiLCJpc3 MiOiJodHRwczpcL1wvbG9jYWxob3N0Ojk0NDNcL29hdXRoMlwvdG9rZW4iLCJleHAiOjE1MTA4MjQ5MzUsImlhdCI6MTUxMDgyMTMzNSwianRpIjoiNDA1YjRkNGUtODUwMS00ZTFhLWExMzgtZWQ4NDU1Y2QxZDQ3I n0.FCk3Wo8DnFEHb02JCd9BWAHQ48BBt3n2YLQV6TpLMpFvTRNCZJAA-aEH4LrE7oVejvGd7YWGDy2Vzb7x-Bpg7yMYxozUerCkMy_F4Iw_xctgEJ3WF_TTJFhISGNoWlFXspM5d9EQvMvk0JxAovhE0HfXv5GCosGy -0oT7ShQrwZLBIwE9d0ceUcmly42dvDZSsqHDIzPjrFzvpXwbZqq_sRFnh6MHlmmug7t1UCs85caoLhfSweaT0z7ED8P2Tsg_HgmnaaeDapszG6LckeBglqYwbRHy6X6LAcJfAkkwAlqrU0Vu4azsuE8BsLPKMYzu9Ze CoHdLHYdtz-I0yKQ
The self-contained access token has three parts: header, payload and the signature.
Following are some of the JWT claims in the self-contained JWT tokens:
Claim name | Claim type | Claim value |
iss | string | The issuer of the JWT. The ‘ Identity Provider Entity Id ‘ value of the OAuth2/OpenID Connect Inbound Authentication configuration of the Resident Identity Provider is returned here. |
aud | string array | The token audience list. The client identifier of the OAuth clients that the JWT is intended for, is sent herewith. |
azp | string | The autorized party for which the token is issued to. The client identifier of the OAuth client that the token is issued for, is sent herewith. |
iat | integer | The token issue time. |
exp | integer | The token expiration time. |
jti | string | Unique identifier for the JWT token. |
Access tokens are credentials used to access protected resources. An access token is a string representing an authorization issued to the client. Tokens have scope information and duration of access. Access tokens do not have to be in any particular format. OAuth servers have defined their own different formats. 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 to use the access token. Following should be noted about access tokens:
- Access tokens are not meant for client so client should not read or interpret the access tokens.
- Access tokens do not reveal user indentity and information to the client.
- Access tokens should only be used to access protected resource from the resource server.
Once the client has the token, then this token can be used by the client to access the resource server on user’s behalf without using the username and password anymore. Due to this reason, the access token should be considered as a sensitive information by the client and must be kept secure. If the client uses the access token to communicate with the resource server then it should be over SSL. It is very important that the access token is stored secretly and is not stolen.
5.3 Refresh Token
Refresh tokens are credentials used to obtain access tokens. One use case of refresh token is when the current access token expires, refresh token can be used to obtain a new access token.
5.4 Scope
Scope in OAuth 2.0 defines the limit on access of an application to the user’s account. An application can request for scope(s), this information is presented to the user in the consent screen. The application is granted access to these scopes only. OAuth 2.0 specification does not specify values for scope as this can vary for every application.
6. OpenID Connect
When user authenticates with the authorization server, the authorization server will issue and provide the client application with an access token. Now this access token can be a simple, alphanumeric, random string of characters that does not contain any details about the currently authenticated user.
OpenID Connect was designed as an additional layer to provide our client application with information about the currently authenticated user. So an OpenID Connect comes as an additional layer on top of OAuth two, and it is an identity layer that can provide the client application with an identity Information about the user.
The authorization server that supports OpenID Connect and provide client application with the identity information is also called an identity provider.
When user authenticates with the authorization server, the authorization server will issue and provide client application with an access token but with an OpenID Connect the authorization server, will also provide client application with an ID token.
The ID token contains user identity information and the client application can use this ID token to extract from it some basic information about the currently authenticated user.
So the client application will now have two tokens the ID token and the access token. The ID token will be used to validate that a user is who they claim to be, and an access token is used to validate if the user is allowed to access a requested resource from the resource server.
7. Conclusion
In this tutorial, we discussed the OAuth 2.0 protocol flow. The understanding of the OAuth flow is very important to understand its implementation and various use cases.