OpenID Connect

Simon Payne
THG Tech Blog
Published in
4 min readOct 31, 2018

So… you want to secure your services?

At THG we have been successfully rolling out OpenID Connect across our systems and I would like to share some insights to maybe ease your future pain :)

Unless you have studied the subject, it can be fairly complex. The specifications can make for difficult reading and lots of conflicting information can be found on the internet. Understanding the basic use cases and practical applications can be more challenging when buried within technical jargon. Hopefully, this series of posts can help you to get started.

Typically, components created at THG are either browser based JS applications or RESTful APIs and often a combination of both.

So let’s start by considering our most basic component of the system, our resource server….

Securing the RESTful API — Authorization

In the modern world of scalable micro-service driven architecture, we push towards high performance with a low memory footprint. In this world, securing the service needs to be inexpensive. This poses the problem of how can we scale if we need to maintain authentication or authorization state? Enter the stateless service and delegated authorization!

So given that our services are stateless, the authentication and authorization state must therefore have an alternative source of truth. Delegated authorization simply implies that the user has elected to give the responsibility of managing authentication and authorization to the external authorization service, be it facebook or google for example. In our case this would be our corporate identity provider.

After successful authentication, the identity provider then represents state through the issue of identity and access tokens.

{    “access_token”: “xxxxxxx.xxxxxxxx.xxxxxxxx”,    “expires_in”: 300,    “refresh_token”: “xxxxxxxx.xxxxxxxxxx.xxxxxxxx”,    “token_type”: “bearer”,    “id_token”: “xxxxxxxx.xxxxxxxxxx.xxxxxxxx”}

In the following illustration, a client is identifying itself to the identity provider, which in turn issues the token bundle. The access token is then extracted from the payload and passed to the RESTful API within the request headers. This provides our most basic interaction, or use case, of OpenID Connect and is largely covered by the OAuth 2 Authorization Framework and OAuth2 Bearer Token Usage specifications.

The access token is then validated at the resource server according to the JSON Web Signature (JWS) and JSON Web Token (JWT) specifications. Only after this can we trust the authorization claims contained within the access token. Note that the intention of the access token is in providing authorization claims only, NOT as a means to validate the users identity.

However an important dependency now exists in obtaining the public key of the identity provider. Reading the JWS specification we see that we need this to validate the token signature.

This is normally achieved in one of two ways. A run-time request to the identity provider to obtain the key, or providing the key to the component environment during the deployment phase.

OpenID Connect requires a discovery endpoint to be provided to the client to ‘discover’ the endpoints. This would also include the location of the public key.

Identity — Authentication

When considering the token response seen earlier, you might notice the similarity to OAuth 2. That’s because it is!

OpenID Connect is built on top of OAuth 2, therefore you will see that many of the specifications quoted in OpenID Connect are referencing the OAuth 2 specifications. The additional elements mainly focus on the identity elements and authentication.

To quote the specification

The OpenID Connect Core 1.0 specification defines the core OpenID Connect functionality: authentication built on top of OAuth 2.0 and the use of Claims to communicate information about the End-User.

This means that we now see the addition of the id_token in the token response.

This token is intended for use by the client application to understand the authentication state of the user. It is not an access token intended for authorizing the access to a resource! An example use case might be where we want a lightweight means of showing the username of the logged in user.

However, it must be mentioned that just as the access token is validated by the resource server before trusting its contents, so must the id token by the client.

So, adding this into the sequence diagram we might see the following usage.

Conclusion

We’ve now seen a simple use of OpenID Connect which allows us to use both the access token to access the secure resource and the id token in the identification of the authentication state of the user.

We’ve also made a clear separation between Authorization and Authentication.

access token = authorization claims

id token = authentication claims

I’ve intentionally steered clear of too much technical detail — hopefully this has allowed some of the key concepts to come forward. Next time, we’ll go into more detail and also look at some alternative flows and use cases.

Until then you should find plenty of links to the OpenID Connect and OAuth 2 specifications to make for some happy reading! :) Enjoy.

--

--