OAuth and OpenID Connect: A Background Check

Chamath
14 min readMay 13, 2021
Photo by Markus Winkler on Unsplash

Hi, this write-up is purely meant as a guide for those who are out there (like myself) trying to work their way through understanding OAuth and OpenID Connect. In my modest experience, the three things that are making OAuth and OpenID Connect difficult to understand is,

  1. The heavy technical jargon surrounding the specifications.
  2. The fundamentally complex (and brilliant!) nature of both OAuth and OpenID Connect.
  3. OAuth 2.0 and OpenID Connect being very similar from a beginner’s POV.

And even if you get past the dense terminology, understanding these specs can be pretty overwhelming given their scopes. After all, they were designed to solve complex web security problems (including edge cases) in vastly different environments.

In this piece, We are not going to go over the grant-types in OAuth 2.0 or the authentication flows in OpenID Connect. Instead, We will steer clear as much as possible from the technical jargon and try to understand the fundamental ideas behind OAuth and OpenID Connect and why these specifications came to place. Then on, you will be able to dive deep into the specifications with a much more holistic view (I hope).

To start, we need to know the problems which conjured these specs into existence :D. Let’s go back a few years.

Infamous Yelp

So, around 15 years back, there was no mechanism to grant an application with controlled access to resources. Let’s take the example of Yelp circa 2006 (sorry, Yelp).

At the time, Yelp was still an emerging business with their core service being hosting and managing crowd-sourced reviews about businesses.

As a way of improving the user experience, Yelp had this feature where the users would be able to connect with their gmail contacts on Yelp. This is a common use case that is supported in almost all of the online services that we use today. However, back then, Yelp implemented this feature in a rather rash way by today’s standards. Here’s the famous excerpt from the Yelp account creation process where this feature was implemented.

Here the idea was that the user would tell Yelp what email service they use, then provide the login and password information so Yelp can determine if any of the user’s email contacts are Yelp members. It goes without saying the security threats this entails since email credentials are basically the de-facto entity for your online identity. Even though Yelp meant it well to access the contacts of your gmail account, giving out the email credentials to a third party means they can do anything with your gmail account. Despite how trustworthy Yelp is, you are at the mercy of Yelp with regards to the things they can do with your gmail account.

Yelp had to resort to this option because, at the time, there was no proper mechanism in place to grant delegated authorization for an application. If there was a way to let Yelp only access the contacts and do nothing else, these risks could have been averted, and at the same time, the users could also benefit from the enhanced experience. To address this problem OAuth; a solution billed as an open standard for API access delegation was introduced.

A Valet Key for Web Services

The idea behind OAuth was to provide a special key for web services. Think of it as a valet key for luxury cars.

What’s a valet key? So a valet key is a special kind of key that you give the parking attendant and unlike your regular key, will not allow the car to be driven for more than a kilometer or two. Some valet keys will not open the trunk, while others will not unlock your front cabin. Regardless of what restrictions the valet key imposes, the idea is very clever. You give someone limited access to your car with a special key while using your regular key to unlock everything. This was the same idea that was introduced with OAuth, a valet key for websites.

Yelp with OAuth Protocol

Let’s see how the same use case (Connecting your gmail contacts to Yelp) can be achieved without having to compromise your gmail credentials. This time with the OAuth protocol.

First, you will start with a button on Yelp that says something like “Sign in with Google”. When you click on that, you will be redirected to Google. Specifically, to Google’s authorization server.

Then, Google’s authorization server would ask the user their gmail credentials. Here as a user, you would be more comfortable with providing the credentials because you’re giving the credentials of your gmail account to Google itself.

After Google authenticates you with the given credentials, they will prompt you with a consent dialog basically asking whether you would like to share your email address with Yelp. If Yelp required more information or more privileges on your gmail account, Google’s authorization server will let you know that these are the information and privileges Yelp would like to have on your behalf. Here, as the user, you would have the full autonomy over the information and the access privileges that is being shared with Yelp. Now you are explicitly given the opportunity to accept or deny the sharing of your details that Yelp is asking for.

In case you give your consent, you are redirected back to the original application, which in our case is Yelp, and you will be redirected to a special place on Yelp called the “callback URL” or the “redirect URL”.

Then after a few requests, Yelp would be in possession of something called an “Access Token”. So, this access token is similar to the valet key for cars which we talked about earlier. Normally, Yelp would not have access to your gmail contact list. Now, with this access token; this special valet key, Yelp can now go to Google, more specifically a resource API of google (In this example, contacts.google.com), and ask for the information that you agreed to share on the consent prompt in step 2.

Google’s authorization server would then validate the access token and see if you have given consent for Yelp to access this information Yelp asks for. If the access token is valid, Google will give out the information, only the information and privileges you agreed to share, back to Yelp.

While this example summarizes the basic flow of delegation of authorization with OAuth, it also brings up two main concepts in OAuth, “Scopes” and “Consent”.

Scopes and Consent

So, with our example, you can see that Oauth is about authorization and permissions. But authorization and permissions only make sense if you can make them granular. There is no point in having only the two options of full access and no access. In our example, Yelp only asked for the user’s contact list. This granular access delegation has become possible with OAuth with its concepts of Scopes and Consent.

The idea of scopes, going back to the example of valet keys, is the amount of control you want to grant. In the case of the valet keys, it can allow the car to be driven only for up to a kilometer. Or it may allow the the car to be driven for a kilometer AND allow the parking attendee to open up your car trunk.

With scopes in OAuth, we are doing exactly that. OAuth scopes say that the application will have access to only these specific sets of information and privileges instead of giving access to the whole account.

On the other side of “Scopes”, we have the idea of “Consent”. Whichever the information and privileges the application asks for in scopes, the users have the autonomy of granting that access, in other words, providing the consent.

So with the ideas of Scopes and Consent, the application tells via scopes that these are the things I want to do with your account, and the user would explicitly have to give their consent that they will allow the application to do what they say they want to do. With this mechanism, the application would have to lay down what kind of information and access it wants from the user’s account at the very beginning. Then the user will see whether if the application is asking for the correct permissions to do only the things that they asked for. Now, the user won’t have to blindly trust the application. They will know what kind of privileges the application would have if the user gives their consent.

To summarize, with the concepts of “Scopes” and “Consent”, the application wouldn’t be able to access information and privileges which it didn’t request and the user would know the exact privileges that they would grant the application on their behalf.

This transparency not only gives the user to have control over the information they’re sharing with the application, but now the user won’t have to blindly trust the application like they would have had to in the Yelp example we discussed at the beginning.

OAuth for Authentication (?)

With its introduction, the OAuth protocol solved a problem that many of the web services were struggling to find an answer to, like the problem we went over in the Yelp example. Because of that, OAuth protocol was widely adopted and they even came up with an update to the protocol named OAuth 2.0.

As we discussed before, OAuth protocol was built for the delegation of authorization, that is exchanging permissions between systems. That was the objective the protocol was built around to cater for… originally.

But because the protocol was so popular and everybody started using it, it was tempting to use it also for authentication. So, circa 2009, OAuth 2.0 was used not only for the purpose of delegating authorization, but also for log-in for native apps, single-sign-on use cases, and even for the simple log-in stuff.

But the main thing that pushed OAuth 2.0 to be a mainstream tool for authentication was social log-in.

This was the time when Facebook introduced the “Facebook login” button, which was something new at the time, where you could use your Facebook account to login and access other web sites. From a user’s standpoint, this was very convenient because as a user, with a single click, now you could use this one Facebook account for every other site you want to access without having to create a separate new account.

But… this was OAuth 2.0 being misused for authentication. This was not what OAuth was originally meant for.

Side note:

This is one of the reasons why it can be challenging to learn about OAuth online. Simply put, it creates confusion. In one forum you will see people talking about OAuth as an authorization protocol whereas in some other forum, you will see people talking about OAuth being used for authentication which is a context that it wasn’t meant to be used.

Now you might ask,

“Okay, OAuth 2.0 was originally meant as a protocol for delegated authorization. But why can’t we use for authentication as well?”

Short answer is, it can be used for authentication. Facebook already did it back in 2009.

But just because it “can” be used, should it be used?

Well, it depends on the way you do it. And certainly, there are risks to it. Let’s take a closer look.

Pitfalls with OAuth for Authentication

Before looking at why it is bad to use OAuth for authentication, let’s see what an authentication protocol should do.

So, authentication basically tells an application who is the current user and whether or not they’re present. With a proper authentication protocol, the web site (“client”, in OAuth terms) would also get a set of user attributes like a unique subject identifier, user’s email address, and other attributes about the user that are useful and can help in identifying who just logged in. So, to summarize, we can say Authentication is all about the user and their presence with the application.

Think of it this way. Imagine you’re building an authentication system for your website. So when somebody logs in, naturally the first thing you would want to know would be “Who just logged in?”. In terms of information, you may want to know the user name or the email address of the user that just logged in at least.

But the problem with OAuth is that, it tells none of these information about the user back to the web site (client). Sure, it cares about the permissions the user gives and the scopes. It cares about tokens. But it doesn’t care about who the user is necessarily or whether the user is present when the service accesses a resource on their behalf. In fact, much of the point of OAuth is about giving this delegated access in situations where the user is not present. (Think of the valet key analogy).

Another concern with re-purposing OAuth 2.0 access tokens for authentication is that the motivations of the participants are different between Authentication and Authorization.

In the authorization case the client can be trusted with the access token because it has no real motivation to share it. The problem is that in the authentication case, websites do have a motivation to inappropriately reuse the access token. The token is no longer just for accessing the protected resource, it now carries with it the implicit notion that the possessor is the resource owner.

Now you might say, having a valid access token is enough to prove that the user is authenticated because at the authorization server, the user is being authenticated when access token is freshly minted. But, this is not always the case. With OAuth 2.0, this is not the only way a website (a client) can get hold of an access token. There are mechanisms like refresh tokens and assertions where an access token can be obtained without the presence of a user. Hence, the idea that having a valid access token proves that the user was authenticated is false.

In cases where OAuth 2.0 had been re-purposed for authentication, the access token was sort of dual-purposed to retrieve the user information. So when Facebook, Google and everybody built their social login buttons with OAuth 2.0, each one of them built some proprietary way, a hack almost, on top of OAuth 2.0 to get user’s info. On Facebook, it was their Graph API endpoint you could call with an access token and get user’s info. It looked a little bit different in Google. And it was a bit different with other services like Microsoft, LinkedIn etc.

So when you have a standard that’s being used in many different ways like that, it becomes very difficult to use. Also, the mechanisms each of the vendors used had their own downsides in terms of security and performance. Hence the need for a common standard to handle authentication came in to light.

Enter OpenID Connect

To solve this problem of standardizing a way to get user’s info while using OAuth 2.0, people went back to the drawing board. Since the OAuth 2.0 was massively popular and had become an internet standard by then, these guys thought,

OpenID Connect was this new standard. More precisely, it was an extension layer on top of OAuth 2.0 specifically made to cater for the authentication scenarios that OAuth 2.0 wasn’t made for.

OpenID Connect added the stuff you needed for authentication and also it tightened up some things like Scopes so that each implementation would start to look a lot more standardized.

Things Added with OpenID Connect

With OpenID Connect, there were a few new components introduced. Among these, the concept of an ID Token was the topmost addition to close out the gaps/issues that were there with OAuth 2.0 for authentication. In fact, one can safely say that the core of OpenID Connect is based on this concept, “ID Tokens.”

Basically an ID Token contains information about the user. These ID Tokens take the form of a JWT (JSON Web Token), which is a JSON payload that is signed, and can be parsed and verified by the application. If you are interested in learning the technical ins-and-outs of ID Tokens, I highly recommend going through Understanding ID Tokens by Takahiko Kawasaki.

So, what happens when a user logs in to a website that uses OpenID Connect is that, the website (client) receives an ID token after the user successfully authenticates. Then it can consume this ID token and extract user information from it, which tells the application who just logged in. Apart from that, the information retrieved through the ID Token can also help in personalizing the user’s experience.

Next major component that was introduced with OpenID Connect to help with authentication use cases was the UserInfo Endpoint. The idea of the UserInfo endpoint was to provide an endpoint to retrieve the user info of the user who logged in. In case the application wants more information than what you get with an ID Token, the /userInfo endpoint could be called with a valid access token to retrieve consented claims, or assertions, about the logged in user.

This was essentially what FaceBook did with their Graph API to retrieve the user info with the access token. With OpenID Connect, the same idea was standardized.

Apart from these additions, OpenID Connect helped in standardizing the implementations. The governing body of the OpenID Connect standard, the OpenID Foundation (OIDF), has worked towards promoting and nurturing the OpenID standards which has helped in the wide adoption of OpenID.

Thereby, OIDF has enabled adopters and implementors of OpenID Connect to certify their implementations. This has been to ensure conformance and to encourage interoperability among implementations. The foundation’s certification process uses the approach of self-certification and conformance to test suites developed by the foundation. Once certified, implementations are allowed to display the “OpenID Certified” certification mark. As you can imagine, this sort of standardization saves the implementors the hassle of mitigating slight differences that was there with OAuth 2.0 implementations.

The idea of this write up was purely to give a holistic view on OAuth 2.0 and OpenID Connect. In what we discussed, we have barely scratched the surface of what these protocols are capable of. But now, I hope you would have a richer outlook on these specifications the next time you read up on something related to OAuth and OpenID Connect.

Finally

If you are looking for an implementation of an OpenID Connect provider, please consider WSO2 Identity Server. Read Configuring OAuth2-OpenID Connectfor more info. Thanks for reading!

References and more resources

oauth2simplified.com

https://www.youtube.com/watch?v=996OiexHze0

https://oauth.net/articles/authentication/

http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html

https://darutk.medium.com/understanding-id-token-5f83f50fa02e

https://uh-ir.tdl.org/bitstream/handle/10657/3381/OFLEH-THESIS-2018.pdf

--

--