Start a Project

OpenID Connect: Extending OAuth Based Authentication

An increasing number of platforms have recently began adopting OpenID to handle user authentication as opposed to OAuth, our knight in the shinning armour. But why?

As an enthusiast programmer, I love OAuth2. It’s an interesting concept, and very well thought. So when I first heard about OpenID, the very first thought that popped in my head was “Why?”. Like any other person, I did what most people would do when they come across something they have absolutely no idea about: ask Google. And much to my surprise, there wasn’t an awful lot explaining OpenID, not on their website anyway. I figured out that OpenID Connect (aka. OIDC) was the current OpenID Standard suited for API-like requests, but as a whole, I didn’t really understand what OpenID does and how it does it.

If you feel like you’re on the same boat as me, or just curious about the technology, this will be a good read for you as I go over the basics of OpenID Connect. For simplicity, will be using a bunch of frameworks and third-party libraries to kick start our project in PHP, but hopefully you’ll get a gist of OpenID.

What is OpenID Connect?

So what exactly is OpenID Connect? In layman’s term, it’s simply an identity layer built on top of OAuth 2. “It allows clients to verify the identity of their users through whatever authentication system they have in place, while at the time, retrieve basic information about the identity of those users”. At first glance, this doesn’t make a whole lot of sense. We’ll get back to this later and see what this statement really means, but in essence, what it simply denotes is that OpenID is not some new standard that’s different from OAuth, but that it deals with the authentication layer in a rather different approach. Under the hood, it’s the good old OAuth2 that’s at work.

OpenID consists of two main integral parties:

For example, I have a website XYZ where I have implemented “Continue with Google” functionality to enable Facebook Users to login to my website through their Google Account. So to put in context of OpenID, Google here is the Identity Provider which holds information about all their Google Users, whereas XYZ website is the Relying Party which communicates with Google (IP) to authenticate their users and in return provide us with a token upon successful authentication. So in essence, what it means is that for one Identity Provider (IP), we can have multiple Relying Parties which relies on the Identity Provider to handle the authentication for users originating from that Identity Provider.

Once the authentication is successful, the Identity Provider (IP) here would in return provide us with an access token, just like any implementation with OAuth2 would. However, the difference here is that in case of OIDC, the token will be in the form of a JSON Web Token (JWT).

 

JSON Web Tokens (JWT)

JWT is an open standard for creating JSON-based access tokens which asserts a number of claims, and are designed to be compact and URL-safe. These tokens are signed using a secret key by the Identity Provider issuing the token. Since the secret key is shared between both the Identity Provider and Relying Parties, it can easily be validated by the Relying Party.

Getting to the structure of a JSON Web Token, it is simply a concatination of three different strings (with a period in between them) which holds different types of information: header, payload, and signature.

Structure of a JSON Web Token

Now that we know that a JSON Web Token is a combination of three different types of information, lets take a look at what they are:

So what we have is basically:

So if we utilize the signatureString part of our token, we can then easily verify the validity of our token. That being said, let’s take a look over at the payload data and understand what it contains.

JWT Payload Data:

The payload data, as in the payload part of our JSON Web Token, represents JWT Claim Set which is basically a JSON Object whose members are the claims conveyed by the JWT. So anything that comes under the Payload Data, is a JWT Claim. There are three types of JWT Claims: Registered Claims, Public Claims, and Private Claims.

 

Registered Claims:

Registered Claims are those claims which hold specific meanings to themselves. Although these are registered claims, they are not mandatory to be included in the payload data.

 

Public Claims:

Public Claims are those claims which we create ourselves to carry additional information along with the payload data, for example: ’email’ claim which holds the email of the authenticated user.

 

Private Claims:

The Identity Provider and Relying Part may agree to usage of certain claims that are private to them, as in claims which are neither a Registered Claim nor a Public Claim. Unlike Public Claims, Private Claims are subject to collision and should be used with caution.

 

Now that we know what a JSON Web Token comprises of, lets get to the implementation of OpenID Connect which will be utilizing JWT.

OpenID Connect

We know that a working OIDC implementation comprises of two parties: Identity Provider which will be providing user identities, and Relying Party, which will be making use of these user identities. So we’ll create two different projects, one will act as an Identity Provider, and another as Relying Party. I’ll go through the workflow of the entire authentication process, but I will only be focusing on the certain part of the project as far as code samples are concerned.

The project I’ll be building will be made using Symfony Framework for PHP. For the Identity Provider project, I’ll be using bshaffer/oauth2-server-php library to implement the OpenID Connect Server. You can go through the documentation on how to do so and implement your own OpenID Connect Server for the Identity Provider.

So let’s get to it. If you are already familiar with the workflow of an OAuth2 Authentication System, OpenID Authentication System is going to work in a very similar fashion:

Step 1: Redirecting user to Identity Provider for Authentication

Some of the parameters here are simply there because of our choice of library we used to implement to OIDC Server on our Identity Provider. You can refer the provided documentation to read more about that.

Step 2: Handling User Authentication on Identity Provider’s OIDC Server

When the user is forwarded to the Identity Provider’s website for authentication, the identity provider will first validate the request to verify the Relying Party. Once the RP has been confirmed, the IP will retrieve the user from the user session and based on that will either present the user with a login page if the session is inactive, else will generate a JWT Access Token and map it with an Authorization Code. If the user session is active, the user will be redirected the Relying Party’s website along with the Authorization Code which will then be processed by the Relying Party.

Step 3: Process the Authorization Code and Retrieve JWT Token

From the Relying Party’s Perspective:

From the Identity Provider’s Perspective:

 

Conclusion

So we just went over the basics of OpenID Connect. It’s been employed by many different platforms, most notably Google. The generated JSON Web Token can be further used to perform api queries depending on the functionalities of the respective platform. In contrast, it’s not very different from OAuth, but at the same time, it’s very different. It’s different in the sense that it extends the functionalities of OAuth2, and with that in place, the generated JSON Web Token can carry additional information and is a bit more secure now that we can cross-verify our token to make sure that it indeed originated from the expected endpoint. In my opinion, it makes sense when you have a bunch of relying parties and would like to use the same token in place for authentication of users across these different platforms which are your relying parties. For example, Google has a lot of platforms, but the users they have are common to one Identity Provider, which is Google itself.

But at the same time, if there’s only a single Relying Party, then I would rather prefer working with OAuth2.

Exit mobile version