OAUTH 2.0: The Basics

Juan Pablo Ortiz Palacio
Globant
Published in
12 min readApr 5, 2022

There are plenty of resources online related to OAuth2.0 and Open ID. A lot of these resources are hard to follow, maybe because of the way they’re presented or because sometimes we have a difficult time when trying to visualize abstract concepts. In this post I’d like to explain with some real-world analogies what I think are the most important ideas to fully understand OAuth2.0 so you can dive deep into more technical resources. The basic concepts that we’ll cover are:

  • Difference between Authorization and Authentication
  • What is OAuth2.0
  • OAuth2.0 roles
  • OAuth2.0 grant types and flows

TL;DR

  • Authentication is the process that focuses on identifying who you are.
  • Authorization is the process that focuses on identifying what you can do.
  • OpenID defines a standardized way to handle Authentication for OAuth.
  • OAuth is an authorization framework created with the goal of providing third-party applications access to restricted resources on behalf of a user
  • There are 4 main roles in OAuth. Resource Owner, Client, Authorization Server and Resource Server.
  • There are two types of clients: confidential and public.
  • OAuth defines 4 authorization flows and 1 extension mechanism.
  • The authorization code flow exchanges an authorization code for an access and refresh token. It is used with confidential clients.
  • The implicit grant is used by public clients. There’s no authorization code and the authorization server must NOT return a refresh token, only an access token.
  • The resource owner password credentials grant implies that the resource owner shares its credentials with the client. The client will use these credentials to get an access token. It should be only implemented for high trust relationships between resource owner and client.
  • The client credentials grant is used for machine 2 machine communication (M2M). In this flow the client sends its clientID and secret to the authorization server. Once the authorization server authenticates the client, it returns an access token. It should NOT return a refresh token.
  • The authorization code and implicit grant flows are redirection based flows.

Difference between Authorization and Authentication

It is important to differentiate between authentication and authorization since this will help us understand what is the responsibility between OAuth2.0 and OpenID. In simple terms, Authentication is the process that specifies how to identify who you are. Authorization is the process that focuses on how to determine what you can do once authenticated.

Let’s check this with an example.

Suppose you receive an order from Amazon but this gets to a package-locker system. Once the carrier leaves your package, the system sends you a code. You go to the locker room, enter your code and then you’re asked to sign on the screen. Once you finish, the system opens one of the lockers so you can retrieve your package. In this example, you authenticate with your code and your signature and get identified as a client. Authorization happens when the system validates your information, sees that you’re a client and grants you access to a specific locker. A system admin for example may have a special code that when validated allows him to open any locker.

What is OAuth 2.0

OAuth is an authorization framework created with the goal of providing third-party applications access to restricted resources on behalf of a user or allowing access to third-parties on its own behalf. Traditionally, users logged in to a system with their credentials but if a third party required access to a specific resource (like your company photo or email) then you had to give them your credentials. This is a problem since you are sharing your credentials and therefore giving complete access to all the information on your account. It’s like giving the pin to your bank account to a financial advisor because he needs to see your yearly bank statements. Usually, the problem was not the malicious use of your credentials but the risks of having them on a third-party. In the example above, if there is a security breach on the financial advisor side, chances are that your information gets compromised.

Imagine that instead of giving your credentials he goes directly to the bank and asks for your statements. The bank calls you back asking if you are ok with the advisor getting that information. If you agree, the bank prints a form valid for a week that specifies that the advisor can check your statement only and gives that to him. This is in general terms what OAuth does. OAuth adds an authorization layer (in our example, the bank) and makes a clear difference between client (the financial advisor) and resource owner (you). It doesn’t use the resource owner credentials to access protected resources, instead, after the resource owner approves, it generates an access token (the form) for a third-party that can be used to access the protected resource.

If you check the OAuth definition, you can see that it is an authorization framework focused on securing resource access, but it doesn’t talk about the authentication part as that is out of its scope. Allowing third parties to retrieve profile information related to the end user to identify them is a process handled by the OpenID protocol. To give a little bit of context related to OpenID, we need to remember that OAuth was a game changer and was adopted very quickly. This led to development teams figuring out the authentication part on their own but as more implementations were built, the misconception of using OAuth as an Authentication mechanism took place. In order to close this gap, OpenID was defined as the authentication protocol and is known as an extension of OAuth.

If we were talking about an ATM interaction, the OpenID role would be represented by the ATM asking for the PIN. When the bank finds your account, the system will return a personalized screen for you, maybe with your name and the last date you accessed the system.

OAuth 2.0 roles

Now that we understand better the difference between authentication vs authorization and the roles that OAuth and OpenID have, to help us understand better the authorization flows, we can take a look at the four OAuth roles, which are the following:

  • Resource Owner
  • Resource Server
  • Client
  • Authorization Server

Resource Owner

This role is usually associated with the end-user but it could be any entity capable of granting access to a protected resource. For example, if the resource is your bank account, you will be the resource owner.

Resource Server

The resource server is a server that hosts the protected resources. In OAuth this role also handles the access requests. In our bank account example, the bank will be the resource server since it is the entity that has all the information related to your account and can handle access requests to it.

Client

The client is a third party application that tries to access protected resources on behalf of the resource owner but always with its authorization. Continuing with the previous example, suppose you apply for a loan to buy a house with a mortgage lender. They will need to access some of your account details, like the balance. As the owner of the account, you need to authorize them to do so, otherwise they won’t be able to get your bank account information.

It is important to know that OAuth defines two types of clients: confidential and public.

Confidential clients are applications that can authenticate securely with the authorization server. This means that these applications can hold credentials in a secure way without exposing them to unauthorized parties. They require a backend server to store secrets.

In contrast, public clients are applications that can’t hold credentials securely. These applications can’t maintain the confidentiality of credentials and for that reason they can’t use registered clients.

Authorization Server

This is the server that generates the proper access tokens with the required authorization to the client after the resource owner authenticates successfully. Going back to the above mortgage situation, once you are authenticated with the bank and authorize the lender to view your account details, the bank will be responsible for giving them the proper access. It’s important to note that you did not give any credentials to the lender, only granted permission to view specific details about your bank account. In OAuth the authorization goes to the client in the form of an access token (usually a JWT).

A JWT or JSON Web Token is a compact JSON object that can be transmitted securely and contains claims represented with JSON structure. The information within the token can be trusted as the claims can be digitally signed, encrypted or protected with a Message Authentication Code (MAC). A key advantage of JWTs is that they can be validated without contacting any third party. For more information regarding JWTs, visit https://datatracker.ietf.org/doc/html/rfc7519

It’s very common that both the authorization server and the resource server are the same entity as in our example where the bank has both roles.

OAuth 2.0 grant types and flows

The interaction between client, authorization server, resource owner and resource server is known as the authorization flow. In OAuth, the authorization flow changes depending on the type of grant mechanism specified by the client.

The following are the four grant types defined by OAuth:

  • Code grant
  • Implicit grant
  • Resource owner password credentials grant
  • Client credentials grant

OAuth also provides an extension mechanism for the authorization grant.

Let’s visualize the following situation.

Suppose you finished writing a book. Before hiring an editor, you need to get some feedback first. You decide then to post your book for others to read on the XYZ WebApp. When you go to WebApp, you’re asked to add your book from your local computer or an online service like Google or Dropbox. You choose to use Google since your document is in the Drive. After you’ve logged in, a pop up tells you that the app will have read access to your documents. You click the accept button and then you’re in the app’s UI where you can select from your documents the ones that you want to share.

The example above describes the whole interaction in OAuth. To understand it better, let’s start by mapping the roles:

Resource Owner: Us, the owners of the book

Client: The XYZ app

Authorization Server: Google

Resource Server: Google (Drive)

In the following sections we will detail the interactions for each one of the flows:

Code grant

The code grant authorization flow is the most common flow used in web applications nowadays. In this flow the client exchanges an authorization token for an access token. It is commonly used for web-apps with server-side components since in one part of the flow the client will exchange its client secret with the Authorization server. This is also a redirection based flow so the client must be capable of receiving requests from the authorization server.

The following steps describe the exchange during the authorization flow:

  1. We open the XYZ WebApp and start the action to share documents from Google.
  2. The XYZ app requests authorization from Google.
  3. Google redirects the Web Browser to the Authentication form so we can Authenticate to Google servers.
  4. We enter our credentials in the form and after login in, we are asked about the different permission we are about to grant to the XYZ WebApp. The authentication request is sent to Google.
  5. Once authenticated, Google returns an authorization code to the XYZ WebApp using a redirection URI.
  6. The XYZ app creates an access token request and sends the authorization code as part of it.
  7. Google validates the access token request. In this step, Google must ensure that the authorization code was issued to the authenticated client and that the code is valid.
  8. An access token is returned to the XYZ WebApp.
  9. With the access token the XYZ WebApp requests data from the Google drive’s API sending the token in the request headers.
  10. The Google drive API validates the token and returns the information to XYZ WebApp.

There are some details in this flow that are worth mentioning.

In step 2, the authorization request includes the XYZ client ID, requested scope and a redirection URI where Google should redirect the browser if the owner grants access. For the request in step 6, it is important to note that the client (XYZ WebApp) authenticates itself to the Authorization Server so the request contains the clientID along as well as the grant type and authorization code. Finally in step 7, Google can return an optional refresh token that the client can use to renew the access token.

Implicit grant

The implicit grant authorization flow was created for public clients like single page applications (SPA) that lack a backend component that handles the interaction with other systems. This means the access token is returned as part of the URL when the client sends an authorization request. The client never gets an authorization code. It’s advised to not use this flow anymore as there are security issues like exposing the access token into the browser history.

  1. We open the XYZ WebApp and start the action to share documents from Google.
  2. The XYZ app requests authorization from Google.
  3. Google redirects the Web Browser to the Authentication form so we can Authenticate to Google servers.
  4. We enter our credentials in the form and submit the login request to the Google authorization server. Then we are asked about the different permission we are about to grant to the XYZ WebApp.
  5. Since we granted access, the Google authorization server redirects back to the client. It’s important to note that the redirection URI contains the access token.
  6. The XYZ WebApp requests data from the Google drive’s API sending the access token received.
  7. The Google drive API validates the token and returns the information to XYZ WebApp.

There are a couple off differences in this flow vs the code grant authorization flow:

  • There is no authorization code exchange in this flow.
  • The access token is returned as soon as the authorization server authenticates and establishes if the owner granted access.
  • Since the access token is returned in the redirection URI, no intermediate credentials are issued.
  • A refresh token is never sent by the authorization server.

Still, in terms of the book example, the flow is practically the same for the end user.

Resource owner password credentials grant

This flow is used when there’s a high trust relationship between client and resource owner like the operating system as the client will ask the resource owner for its credentials, typically through an interactive form. It’s commonly used when migrating old clients with basic authentication and should be used only when redirection based flows are not available.

  1. We open the XYZ WebApp and we are asked to Authenticate with our credentials.
  2. The XYZ app sends an access token request to the Google authorization server passing the resource owner’s credentials.
  3. The Google authorization server validates the request.
  4. The Google authorization server authenticates the XYZ WebApp client and issues an access token.
  5. The XYZ WebApp requests data from the Google drive’s API sending the access token received.
  6. The Google drive API validates the token and returns the information to XYZ WebApp.

In the context of our example, the biggest difference is that the XYZ WebApp will ask us for our credentials upfront then pass them along the authorization request to the Authorization server in exchange for a token instead of redirecting us to the authorization server to authenticate. This is similar to the old Basic authentication flow used by many WebApps some years ago but since we are trying to authorize third parties, Basic authentication should be used as a last resort mechanism. Since our credentials will be shared with a third party, this is a very dangerous practice and has a lot of security implications. This is why this flow is NOT recommended and is used only for high trust relationships between client and resource owner.

Client credentials grant

In this flow, the client requests authorization with its own credentials. This means that it will try to access resources by using its own identity, not on behalf of any user. This type of grant is commonly used in machine to machine communication like with CLIs, daemons or services where the client ID and client secret are exchanged for an access token.

A good example for this could be a trends service that everyday connects to Twitter and queries for the top 10 trending topics. In this example the client registers with the Twitter authorization server and gets a client ID and client secret. Once the service runs, the process will be something like this:

  1. The client sends an authentication request that includes client Id and client secret as well as the proper grant type
  2. The authorization server validates the credentials and authenticates the user. The authentication also works as the authorization grant.
  3. The authorization server returns an access token. No refresh token should be sent back.
  4. The client calls the protected Twitter API sending the access token received.
  5. The Twitter API validates the token and returns the information to the client.

You can see that this is similar to the Resource owner password credentials grant but the biggest differences are that no resource owner credentials are passed to a third party and also, the communication happens on the backend for the implicit grant, making it very difficult to tamper with the tokens.

I hope this article was easy to follow and gave you the necessary information to engage in more detailed technical documentation. For more information and details visit:

--

--

Juan Pablo Ortiz Palacio
Globant
Writer for

I’m a full-time software developer who believes that teaching is the best way to learn anything.