a golden padlock sitting on top of a keyboard
Mon Apr 10

Understanding OAuth 2.0 and OpenID: A Comprehensive Guide

In today’s world, the internet has become an indispensable part of our lives, and with the increase in online activity comes the need for enhanced cybersecurity measures. With cyber threats becoming more sophisticated on a daily basis, it has become critical to protect user information by implementing robust authorization and authentication workflows.

OAuth and OpenID are two of the most commonly used protocols for managing access to online resources, and they are utilized by countless websites across the internet. However, the terminologies and processes involved in these protocols can be overwhelming and confusing for developers who are not familiar with them.

In this article, we will provide an in-depth exploration of OAuth 2.0 and OpenID and highlight their significance in today’s world. It is essential for web developers to have a comprehensive understanding of these protocols in order to effectively manage access to online resources and protect sensitive data.

OAuth 2.0

What is OAuth 2.0?

OAuth 2.0 is an authorization protocol or framework, which allows a third- party application to use specific and limited access to the resources owned by the user without having to share the user’s password. In modern times, this has become a widely adopted standard for web applications and APIs.

While OAuth is heavily implemented in web applications that utilize both frontend and backend, there are cases where only one of the two is available. For instance, a Single Page Application with an API may only have frontend access, while microservices may only have backend access. In such cases, the OAuth flow differs depending on the type of access. Implicit flow is used for frontend-only access, while client credentials flow is used for backend-only access.

However, in this article, we will be focusing only on web applications that utilize both frontend and backend, as this is the most common and often the most complex implementation flow.

Why OAuth 2.0?

Probably, the most compelling reason to use it is, it allows applications or clients to access user data without requiring the user to share their credentials, which enhances security. This is particularly important as it prevents the user’s credentials from being compromised if the client’s website is subject to any malicious activity.

If an attacker manages to steal a user’s data, in the absence of the user’s credentials, they will only have access to the specific information that was stolen and will be unable to access any other user data. This unique feature of OAuth 2.0 ensures that passwords are never shared, resulting in a more secure authorization process for accessing protected resources.

OAuth 2.0 terminology

  • Resource owner (e.g. Joe) - The user who owns all the resources and the information the client or application wants to access, e.g. full name, email, contacts, location and so on.
  • Client (e.g. binaryte.com) - Refers to the application who wants to access the user’s information or resources.
  • Server (e.g. Google) - Server refers to two different entities (authorization and resource server) at once as these can be separated into two different servers or packed into a single server.
  • Authorization server - The server that serves authorization permission to the user.
  • Resource server - The API server that stores the user’s resource the client needs.
  • Redirect URI - A location where the server needs to redirect back to, also known as callback.
  • Access token - A key that the client can use to access the resource they are asking from the resource owner to the resource server which has been granted by the resource owner.
  • Scope - Level of access granted to an application by the resource owner, such as read or write access to certain resources.
  • Consent - Prompt that specify desired level of access to specific resources requested by the client to the user.
  • Back channel - The way the client communicates with the server (through API, HTTP request, websocket, etc) directly.
  • Front channel - The communication that happens in a browser (user-agent), where the user interactions happened.

How does OAuth2.0 work?

Assume that this website (binaryte.com) allows everyone to sign up and login (e.g. selling VPS, so by sign up and login, you can access your dashboard and start your own VPS). You, as a user, want to sign up which requires you to first login into your Google account. At this point, we now have three different entities, you (the user/resource owner), this website (the client/resource owner), and Google (the server/authorization & resource server).

For explanation purposes, let’s simplify them as Joe, the client, and the server.


High level overview

Front Channel

1. Initial request (user - client - server)

When Joe clicks “ Connect with Google ” on the client website Joe is basically asking the client to work on his behalf to access a particular resource owned by Joe to the server. The client then sends a request to the server for the resource it needs.

2. Logging in (user - server)

The client redirects Joe to the authorization server owned by Google. Joe will be required to enter his login credential owned by the server.

3. User approval (user - server)

After logging in, Joe will be asked to give particular permission of the resource owned which is required by the client. Say that we need Joe’s profile including his full name, phone number, address and contact. The server knows all of these by checking the previously sent scope parameter that specifies any of these (see initial request in low level overview). Because of all of these resources owned by Joe, the server will ask for Joe’s consent regarding the access of corresponding data required by the client.

4. Callback (server - client - user)

After giving his consent, the server will redirect back to the client website which is identified from the redirect URI. Now, the client has Joe’s consent regarding the corresponding resource. At the same time, the client receives the authorization code from the server.

Back Channel

5. Exchanging authorization code with access token (client - server - client)

Client needs to contact the authorization server to validate the authorization code in order to verify whether the client is legitimate or not (client to server). If the authorization code is valid, the authorization server will send the access token which can be used by the client to access the Joe’s resource which is stored in the resource server (server to client).

6. Client obtaining the resource (client - server - client)

If everything works correctly, the client can then obtain Joe’s resources from the resource server in exchange with a previously granted access token which has a limited level of access based on the endpoint the client is trying to access.


Low level overview

The following information provides significant details that complement the high level overview.

Front Channel

1. Initial Request

Example URL:

	https://accounts.google.com/o/oauth2/v2/auth?
	client_id=ab1234
	&redirect_uri=https:/binaryte.com/callback
	&scope=profile
	&response_type=code
	&state=xyzQWE123

At first, the client sends an URL request with several parameters. The client_id is used by the server to identify a specific client. The redirect URI informs the server what URI should the server redirect back at the end of the OAuth 2.0 workflow process. Client also includes scope, which specifies requests for particular resources owned by the user. The response type=code specifies what the client expects from the server. In authorization protocols, a state parameter is included to enable the restoration of the previous state of an application. This parameter retains specific state objects that were initially set by the client in the Authorization request and makes them accessible to the client in the response. It plays an important role in mitigating CSRF attack.

2. Callback

If user choose “no” in consent page:

Example URL:

	https://binaryte.com/callback
	&error=access_denied
	&error_description=”The user does not consent.”

If user choose “yes” in consent page:

Example URL:

	https://binaryte.com/callback
	&code=abc123def567
	&state=xyzQWE123

Back Channel

3. Exchanging authorization code with access token

a. Client sends authorization code to authorization server

Example HTTP request:

			POST www.googleapis.com/oauth2/v4/token
			Content-Type: application/x-www-form-urlencoded

			code=abc123def567
			&client_id=ab1234
			&client_secret=secret123
			&grant_type=authorization_code

code refers to authorization code the client would like to use for access token exchange. The client_id is a public identifier for applications that should be unique. By public, it means that it is okay to expose the id to the public. As opposed, the client_secret is supposed to be known only by both the client and the authorization server. One effective method to create a secure secret is by utilizing a cryptographic library to produce a 256-bit value and subsequently converting it into a hexadecimal form.

The last parameter is grant_type. We need to specify this based on our use case because there are many types available such as client_code, refresh_token, authorization_code, etc. We choose the grant_type=authorization code as we would like to use this.

b. Authorization server sends access token to client

Example HTTP body response:

		{
 			"access_token":"b1f335be07a3deea0ff38150b1649f56",
 			"token_type":"Bearer",
 			"expires_in":3600,
		}

The access_token is the token used for accessing the resource. This token will be used by the client by sending it to the resource server on its HTTP request header. Again, the server will send the type of token being sent as it can be another one (e.g. mac), but the Bearer token type is most common nowadays.

4. Requesting resource with access token

**a. Client sends access token to resource server **

Example HTTP header request:

		GET googleapis.com/auth/endpoint
		Authorization: Bearer b1f335be07a3deea0ff38150b1649f56

Using the access token, the client is now able to send requests to particular endpoints to obtain the resource based on the previously mentioned scope.

b. Resource server sends user’s resource

Example HTTP body response:

		{
 			"sub": ab13sd1234
 			"email": [email protected]
 			"given_name": Joe,
 			"family_name": White,
 			"name": Joe White,
		}

The resource will be sent in the form of a JSON object in the response of the HTTP response based on the endpoint and the permission granted by the user to the client.


Additional information

To get an improved security, OAuth utilizes both authorization code and the token access thus allowing the collaboration of back channel and front channel.

What do we mean by this?

Front Channel

On the front channel, the attacker may steal everything from the user, whether the redirect URI, authorization code, or anything that is being exchanged. While this is technically possible, it will be rendered useless as the entire workflow requires authorization code exchange with token access (see point 5 in high level overview).

Back Channel

On the back channel, this step requires the client to send its client_secret which is only known by the client and the authorization server. This authorization code works as a validation that the request comes from a legitimate client by checking the authorization code, along with the client_id and client_secret. Unless the OAuth 2.0 workflow is correctly implemented, the attacker is supposed to compromise the network where the client (website) is hosted, which is way more difficult to do.

If the attacker is able to steal the access token from the back channel, it means that the attacker will be able to access the granted permission that is supposed to be utilized by the client, and for this reason, the access token can be considered as the sensitive information itself. To further enhance security, the access token has a limited validity period, after which it will expire and can no longer be used to access the protected resources.

Summary

In the context of security, the front channel plays a critical role in authenticating the user and obtaining their consent for accessing the requested resources. The back channel is utilized for authorizing the client and validating the request to ensure that it originates from a legitimate source. By leveraging the strengths of both channels, the system can effectively mitigate the risks associated with each channel and provide a robust and comprehensive security framework.


**OpenID **

What is OpenID?

It is common to see how OpenID Connect goes hand in hand with the OAuth 2.0. Put simply, the OAuth 2.0 is meant for authorization while OpenID is meant for authentication. You can think of it like the extension of OAuth 2.0

OpenID workflow

Both OAuth and OpenID workflow are basically the same. Yet some differences do exist. On the initial parameters, the scope parameter is specified to openid to inform the server that the request is OpenID and not OAuth.

Another difference is that at point 5 in the high level overview, the client will receive the ID_token alongside the access_token. The ID_token being sent is in the form of JSON Web Token (JWT). If you try to decode the token, it contains the information of the corresponding user (such as name, email address, etc). If you are not familiar with JWT, you can learn more about it here.

Conclusion

OAuth 2.0 has emerged as the standard for secure authorization, providing developers and businesses with a powerful tool to manage access to protected resources. With its support for a wide range of use cases and workflows, OAuth 2.0 has become a popular choice among developers and businesses alike.

However, it is important to approach the implementation of the OAuth 2.0 workflow with care, as its complexity can make it easy to make mistakes. Ensuring that the workflow is implemented correctly is crucial to avoid potential security vulnerabilities and protect sensitive data.