The world of authentication and/or authorization of OAuth and OIDC authentication is a vast one and can be easily misunderstood.

I think that one of the most obscure topics I personally found to be not well understood, having too many approaches, having many posts that misguide, and so on… are quite astonishing.

It didn’t happen because people wanted to mislead, it happened because OAuth and OIDC aren’t that straightforward protocols, and they have a few flows that they implement for various use cases, so misunderstanding how to use them could happen easily because they can be used for multiple use cases that could confuse us easily.

This post is for finally making a drill-down understanding about what is OAuth and OIDC so will finally understand what they are, how they work, their various use cases, and understand actually how to implement them, but most importantly show off at the office that we’re masters at them 😎

Before We Start

We’re going to cover multiple topics that are relevant for understanding client-server communication, so in case you wish to read a previous post that would allow to understand that better in case you need it.

Photo by Pixabay: https://www.pexels.com/photo/road-landscape-nature-sky-56832/
Photo by Pixabay: https://www.pexels.com/photo/road-landscape-nature-sky-56832/

OAuth and OIDC TL;DR

  • Developing authentication and authorization could be quite challenging, so let’s leverage someone else’s authentication mechanism and the time that he’s invested.
  • There are many mechanisms built on top of OAuth and OIDC according to architectures, and because of that people referenced one of them, and probably confused someone else.
  • We depend on the front channel for dealing with not too much sensitive information and allowing the backend for the more needed secured operations to get involved for us more because we depend on it more security-wise than the front-end.
  • OAuth 2.0 usage was leveraged and gave the raise of “hacked” solutions to provide authentication on top of a protocol that was meant to be used in authorizations only.
  • OAuth 2.0 is for authorization, while OIDC is for authentication.

Let’s Go To The Basics

When we’re talking about authentication, we right away see in our head an authentication page where we put a username and password, which is gonna be handled by the application to understand if we say who we are and get inside into the system.

Once we’re inside the system, we can basically do whatever we wish to. It can be from accessing resources like Active Directories, shared file systems, shared servers, AWS accounts in some cases, and so on ..

So of course here we need to add an authorization phase to understand after we said who we are, we are authorized to make operations/decisions according to our permissions.

Something that is quite a challenge here is handling the authentication and authorizations in applications. It can be from implementing a secured flow from the frontend applications, which can be mobile, desktop, and/or browser-based applications, implementing the logic at the backend, and being with the finger on the trigger to do changes when security braces regarding new CVEs, breaches in the implementation, or anything else that put our users at risk.

This might sound quite straightforward, but unfortunately, it’s not. Not everyone is aware of the entire system flow, not everyone is available for the core business logic to go right away and implement it, and not everyone might be able to do the changes in a short amount of time due to the requirements of the product they’re working on, and many other reasons.

As we understand, maintaining and developing an authentication and authorization mechanism in our product can be quite challenging, so because of that in our history, we understood that we need to do something else. A simple solution is – why not leverage someone else’s work that he has invested a lot of time and money to develop his mechanism, but also is already being used by many people to maintain an existing account?

Delegated Authorization

At one point of time in our history, Yelp developed a mechanism that allowed us to insert our GMail account at their (Yelp) website, and yea I meant to write to put your GMail account details which are the email address(username) and your GMail account password. By doing so, you’re allowing Yelp to access your Gmail account in the Google domain of GMail.

As we see, this allows Yelp to be your man in the middle to access your account on Gmail to authenticate, authorize, and also gather the information he(Yelp) needs to allow us the service we wish to get out of Yelp.

But wait .. we jumped right into the water without talking about the title we have here “Delegated Authorization”.

This title, as we understand it, is allowing someone else to authorize me into a system, or more precisely, it allows for authorizing an application to give us some kind of service by authorizing us into it by someone else.

In the simplest case, we can think of, it’s like we’re downloading our new game on our mobile from the annoying Ads, and they ask us if we wish to log in using our Facebook, or Google account.

In this case, the game, let’s call it the game “Rocking Soccer Player Ido and Astronaut in Space”, the game implementation goes to Google and gives him a request to authorize me, once trying to login into the game by leveraging my Google account information. It does this by telling Google “Hey, I wish to authorize Ido to access my account by accessing his X of pieces of information on your servers”. Once I press that I authorize in the app that I allow RSPIAS(yea I’m that lazy to copy-paste even the log name), google servers redirect me to the user back by using a sent callback URI back to RSPIAS in order to get back to the page RSPIAS wants me back to, and start using it as needed.

What happens now is that when coming back to the RSPIAS application, it can access Google by passing values of the authorization confirmation flow, and by doing so, access the user information as needed.

Simple right?

Now let’s get our hands dirty even more.

Some Terminology

  • Resource Owner – It’s the person who is the owner of the information that resides in Google according to our example, which was me for that matter here.
  • Client – The application which acts on our behalf that gives some sort of service to us.
  • Authorization Server – The server which authorizes the client to access the resource owner data, which in our case here was Google.
  • Resource Server – It’s simply another Google server that has our information, that the Client application will try to access after being authorized by the Google authorization server.
  • Authorization Grant – Once the Resource Owner authorizes the Client application when the authorization server asks us in the flow and we do authorize the Client to access our information, the Client application will receive an Authorization Grant, which implies that the Client was granted permission to access the Resource Owner data.
  • Redirect URI – Once the Resource Owner clicked “Authorize” or not authorized for that matter, the Authorization Server needs a URL to go back to, meaning to go back to from where we originated from in the first place, which is the Client application. Because of that, the authorization server has the redirect URI in order to understand how and where to go back.
  • Access Token – After the Client application receives an authorization grant after the resource owner is authorized, of course, the Client can use this authorization grant and receive an access token. This is in favor of using that access token for an X period of limited time, which is what the Client wanted to do in the first place, which accesses the Resource Server that has the Resource Owner information. But how do we limit the access to that data?
  • Scope – The scope is holding as the name implies the scope of information that the Client wishes to have the ability to access to once he will have the access token. This scope of the requested information would be presented to the user as part of authorizing the Client application.
  • Consent – The consent is related to the scope because the consent is simply the message screen presented to the user, which the authorization server asks the resource owner if he consents to authorize the client application to access his information on the resource server.

But wait… a question… what do we need the access token from the first place?! Simply a waste of time …

Front & Back Channels

When considering frontend applications, we’re far more easily exposed to more potential exploits/vulnerabilities because frontend applications are simply presented to us in the browser, and by using the browser tools, depending on the web application implementation, of course, we can easily access the app information and maybe leverage it for exposing it to threats.

Because of all of that, we’re doing that the authorization server is sending a grant that simply identifies “The user granted you the ability to access my data at my resource server and this grant is symbolizing that, and nothing more!”.

By having this grant, the Client application, which is limited for that Client application to use, can ask the backend, which is the back channel, to get information by delivering that grant he received.

Because a backend application is more secure than the front channel, the frontend application, we trust it(back channel) to identify the grant(auth server side), and return access token accordingly when exchanging the grant for it. Of course, if the backend application was implemented poorly it can be leveraged for exploits, but it’s still harder to exploit than web applications.

Something else that is important to know is that the communication channel of the Client app and its backend which communicates with Google backend as well was pre-configured with the configuration of a clientID and clientSecret which allows the Client app to communicate with Google from the first place. This is in favor of not allowing anyone on the web to simply tell Google “Hey, I want to start authorization flow with you for some client”, while not having the credentials to start that flow from the first place, but also having the configuration of accessing Google authorization server in a more secure way. 

So if we consider all of these pieces of information together, we understand that the one who is giving us the access token is our Client application backend which communicates with Google to exchange the grant he received earlier.

But another question arises is the fact that the access token is a piece of very sensitive information that could be leveraged by someone else for accessing the resource owner data, which again leads to the understanding that depending on the back channel to use it, is the safer option.

A Quick Pause!

I know it’s tiring reading this and I know because I wrote it 🙂

Anyway, we understood until now that we have a front-end application that allows us to log in to it using our Google account. In the transaction to do so, we, as the frontend application, which is the Client app, request the user to authorize us to access his data on the Google resource server.

When the client approves, we can access it in the image of receiving an authorization grant that signals that the user authorized us, and nothing more.

Afterward, we, in our backend application, which was pre-handed configured with the clientID and clientSecret to talk with Google for OAuto authorizations, to exchange the authorization grant with an access token, which at the end, will be used by us to access the user data at the resource server?

And how will it be used?

Simply adding in our API requests to Google, which of course are done through the SDKs that usually Google and other providers give us, but those access tokens would be used by putting them in an authorization header of HTTP with the type of “Bearer.

Are you with me so far?

Good! It says you’re quite the reader 🤨 🤓

Anyway, let’s continue!

So What Kinds of Flows We have?

We we’ve seen until now called a flow of “Authorization Grant” flow, which you can guess by the name, it implies the fact we use the authorization grant for exchanging for an access token, so you can also guess that the other type of OAuth flows are different, and you’re right on that as well.

What are the others?:

  • Authorization Grant – Uses both frontend and backend applications, which we covered until now.
  • Implicit – In this case, we have only a frontend application, and no backend, we understand when we compare this situation to the “Authorization Grant” flow, we don’t have the backend application for exchanging the grant for an access token, What do we do then in this scenario? Simply requesting the provider, which is Google in our example to give straight back the access token, and skipping the exchanging of a grant with an access token. The way we define this flow is by sending in the “response_type” in the first step to the authorization server to get the value of “token” instead of “grant”.
  • Resource Owner Password Credentials – Only for backend applications. It doesn’t involve the users at all, so it’s straight from our backend to the provider’s backend. This is telling the provider “Hey, I have the credentials of user A that he uses to authenticate with you. Can I have in exchange for that an access token for your resources server information about that user?”. As you understand probably by yourself, it’s less common to use this flow, but majorly used in old implementations that are hard to move for using the other mentioned flows, so this method would probably not be used in new applications.
  • Client Credentials – This flow like the previous one, is used only in the backend. This flow is without having the step of user authorization, but we do have in this flow additional security configurations that allow our backend to request an access token without the user authorization step.

So wait… What is OIDC?!

In history, when OAuth 2.0 entered the playfield, companies, and people started to use it in a way to do simple logins, single sign-on across sites, mobile app login, delegated authorizations, and so on … 

It allowed many implementations of various products to “authenticate” the users into a new platform, based on existing platforms that they have credentials already.

As you understand, OAuth is for authorization but not authentication.

But wait, how can it be that it’s only for authorization you ask?
Simple… each provider has its own information about the users it has. Because of that, each application that authorizes users to its app, won’t necessarily have all the information it needs from the provider that the user authorized the app to access, and because of that, it will need the app to make the “authenticated” user give more information to fill the gaps.

In addition to the fact that there’s no standard way to get the user’s information, there’s no common set of “scopes” of the scope data we wish to get from the client’s resource server, which leads to more problems of a missing standard of what we can get, which again seems like the previously raised issue.

So we understand that OAuth 2.0 was “hacked” in a few ways that would allow implementations to use it in a way that will “authenticate” and authorize the users, so a solution of splitting that problem was needed.

Therefore, OIDC, or OpenID Connect entered the playfield as well.

OIDC acts as an additional layer on top of OAuth 2.0 after OAuth 2.0 flow took place. It’s simply an extension that adds a standard of:

  • ID Token – Represents the information about the user
  • User Info – An endpoint that we can refer to in order to request more information about the user, in case the information inside ID Token isn’t enough.
  • A standard set of scopes 
  • Standardized implementation

But what does it look like in the flow itself?
Simple … the scope in the flow that we go to the authorization server is “openid”. What it does is again the OAuth flow, specifically the “Authorization Grant, and once we get to the step of exchanging it into an access token, we get not only the access token, which we described earlier what it allows us, but we also get an ID Token.

The access token can be of course used to get more information about the user, which is referring the “userinfo” endpoint.

By the way, we don’t necessarily have to use the “authorization grant” flow, but also the implicit flow, so that way we’re saving the backend application as we described before.

But what is an ID Token you ask?

The ID Token is a JWT. It’s a JSON Web Token, that acts as the standard of verifying the payload when we transfer it across the web, but also the standard of putting inside the user information, so that way we finally have a standard of how to send and handle the user information.

The JWT can be verified by a hash functionality to see if it was changed and many other features, so it also allows us to check if the JWT was tampered or not in our implementations.

Again, we can use that JWT by sending it in an HTTP bearer-based authorization header request, and by doing that request to the “userinfo” endpoint, we can get more information if we need any, but of course, it depends on the implementation of your infrastructure and application, so custom implementations can be done of course according to the needs and your solution.

I do wish to state that OAuth can be used for Authentication in a way, but it wasn’t built for it, which lead to the birth of OpenID, which allowed to have a tool for allowing a good protocol for authenticating the users more properly regarding the use cases we need when we develop our solutions, because again, OAuth wasn’t meant for authentication, which has the challenges we described like the standards of using it for gaining information about the user, which leads to scopes standards, and so on …

When to Use What?

Remember the phrase I like to use “Use the right tool for the right job?”.

Then that’s gonna be my answer 🙂

When of course we have the possibility to enforce highly secured solutions, with considerations of time-wise and other constraints, we should always try to strive for them. In that case, the “Authorization Grant” is pretty much the go-to guy if we have a frontend and a backend application that fits the way to use it as we interact with the user.

In the case we have microservices, or basically, only a backend application that wants to interact with our services or even 3rd party ones, we can use the Client Credentials flow which was less talked about here, but on purpose because we can do a whole post only on that.

Regarding OAuth 2.0 and OIDC, we understood that delegated authorization is a classic OAuth 2.0 usage, but when we want to have an authentication flow, we should go to OIDC instead.

Final Thoughts

It was a very long post guys, and I’m sorry for that, but I wished firstly to understand myself fully and not 90% how it works, but most importantly write it in a flow and understandable way for you guys so you would be able to understand it, and how to use it.

Authentication and authorizations are too abstract today for us, and I think that understanding how OAuth 2.0 and OIDC is pretty critical to understanding how we implement our applications regarding the user’s data usage and so on … 

In addition, I really wanted to give all of this information in order to allow everyone to have an ease of understanding regarding these two fellows, because I personally was multiple times wondering what was the main difference, but I also felt like there was something not sitting right, so I thought if that was for me, there are probably other people with the same thoughts as well.

If you think that I’ve written something that isn’t sitting too right with the details, I truly would like to hear it because I tried to take the information from multiple lectures, and content online to make this piece the best as possible, so I do would like to hear your thoughts in case it can be improved, and especially if something wrong was written 🙏

I hope you had a great time reading this piece, and if you have any further questions I would be delighted to answer them.
Also, if you have any opinions or suggestions for improving this piece, I would like to hear 

Thank you all for your time and I wish you a great journey!

  • OAuth & ODIC Lecture of Okta on YouTube “In Plain English” – link.
Author

I simply love learning and improving by what I do, and by doing so strive to achieve my goals which is also help others to achieve theirs.

Write A Comment