Authenticated User ID — An Introduction to OpenID Connect

Whenever a certain application requires your personal details to identify who you really are, you would have to enter your name, phone number, email, etc, into the application to confirm your identity. Or would you really have to?

For example, let’s say that I want to log in to Medium. I already have a Google account and I’m logged in to it from the same browser. When I click ‘Sign in’ the following window pops up.

When I click ‘Sign in with Google’, Medium will send a request to Google asking for an Access Token using the OAuth 2.0 protocol. Once I’ve been authenticated by the Google Authorization server, the following window will then pop up.

OAuth 2.0 protocol is only a means for authenticating users using an identity provider for the benefit of third party applications. So how did it get access to my name (i.e. user info)?

This is where OpenID Connect (OIDC) comes into play. With OIDC, a third party app will be able to securely get the user’s personal information from an identity provider with the user’s authorization. The user will be able to provide access to his identity details with just a few clicks.

What is OIDC?

Simply, OIDC is a secure mechanism for an application to contact an identity provider, get some user information, and return it back to the application in a secure manner. It is an identity layer built on top of OAuth 2.0 protocol. This means that OIDC allows client applications to verify the identity of the End-User based on the authentication performed by the Authorization Server while obtaining basic profile information of the End-User. I have explained about OAuth 2.0 concept in my previous post, so check it out if you want to know more about OAuth 2.0.

In OIDC, an extra token called the ID Token is issued to the client and it authorizes the client to access End-User information. This happens as an extra step in the OAuth 2.0 authorization process. Client applications include openid in the scope of the Authorization Request code and the OpenID Provider authenticates the request and returns two JSON Web Tokens (JWT), the first being the Access Token from OAuth 2.0, and the other being the ID Token from OIDC.

A brief history of OpenID

OIDC is actually the third generation of the OpenID technology.

The first of the generation was the original OpenID. This tool never got much attention from the commercial applications, but it opened doors to new possibilities and got the industry thinking.

Then came OpenID 2.0. This implementation was much more organized and thought through, and offered better security and its operation was pretty good as well. But this also had several limitations as OpenID 2.0 was designed explicitly for web applications only. This means that native applications would still have to open a browser to use OpenID features. Also, the fact that OpenID 2.0 relied upon XML led to adoption problems with the rapidly evolving web technologies tending to prefer JSON instead.

To address all the issues of the former implementations, OpenID Connect was invented. This is much more developer friendly and compatible with most of the web technologies currently available. Any programmer with sufficient knowledge experience to send and receive JSON messages should be able to implement OpenID Connect from scratch.

Entities involved

Before diving into the work flows of OIDC, let’s take a look at the entities involved in the OIDC process.

  1. End-User — Owner of the identity who is using the clients and OpenID providers. This is equivalent to the resource owner in OAuth 2.0.
  2. Relying Party (RP) — Client applications requiring End-User authentication and claims from an OpenID provider.
  3. OpenID Provider (OP) — OAuth 2.0 authorization servers, implementing OIDC, capable of authenticating End-Users and providing Claims to RPs regarding authentication and End-User.

ID Token

This data structure is the extension that OpenID Connect makes the OAuth 2.0 protocol which enables End-Users to be authenticated. The ID Token resembles the concept of an identity card in a standard digital format that RPs can validate. It is a JWT that contains claims about the authentication of an End-User by the Authorization Server or OP.

The ID Token conforms to the RFC 7519 industry standard and is comprised of the following three parts.

  1. Header — Contains the type of token and the hash algorithm used on the token
  2. Body (payload) — Contains the identity claims about a user. The content of the body is elaborated below.
  3. Signature — Signature of the OP which will be used by the RPs to verify the integrity of the contents.

Shown below is the general structure of the ID token body.

{
"iss": "http://server.example.com",
"sub": "248289761001",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"exp": 1311281970,
"iat": 1311280970,
"name": "Jane Doe",
"given_name": "Jane",
"family_name": "Doe",
"gender": "female",
"birthdate": "0000-10-31",
"email": "janedoe@example.com",
"picture": "http://example.com/janedoe/me.jpg"
}

This ID Token contains claims of the End-User’s information along with some other claims that are manadatory for OIDC.

  • iss (Issuer Identifier) An identifier for the issuer of the response.
  • sub (Subject Identifier) — A unique, one-time identifier for the End-User and is intended to be consumed by the RP.
  • aud (Audience) — A set of RPs that the ID Token is intended for.
  • exp (Expiration time) — A time period after which the token becomes invalid and should not be accepted for processing.
  • iat (Issued At) — The time at which the ID Token was issued.
  • nonce — A random string value used to link an RP to an ID Token to help mitigate replay attacks. This is an optional claim. If present in a ID Token, RPs must verify that the nonce Claim value is equal to the nonce value in the authentication request.

There may be more Claims included in an ID Token and any Claims that are not understood must be ignored. ID Tokens must also be signed by the OP using JWS in order to ensure integrity of the tokens.

OIDC Authentication Workflows

Here, we will look into the finer details of how the different workflows of OIDC work.

OIDC performs an authentication process to log in the End-User or to determine if the End-User is already logged in. OIDC then returns the Authentication result to the RP securely. This Authentication result is included in the returned ID Token and it contains Claims mentioned above.

The OAuth 2.0 Authorization Framework (RFC 6749) provides the definition of the Authorization Web APIs used in these protocols. This API requires response_type as a mandatory request parameter. The OIDC flows have been defined based on the combinations of code, token and id token for the values for the response_type parameter. This statement will make more sense when you start reading about the workflows below.

OIDC Authentication can occur in one of the following three paths.

Authorization Code Flow

response_type = code

This flow is designed based on the traditional, three-legged OAuth flow. In this flow, the OP provides a one-time use Authorization code to the RP, which in turn sends the code to the OP along with the client_id and client_secret. The OP then validates the RP based on the information sent and returns an Access Token and ID Token back to the RP. For this flow to work, openid has to be mentioned in the scope of the Authorization request in addition to response_type = code. The RPs using this flow must be capable of maintaining a secret that is unique to them for the use of OP authentication. Long-lived Access Tokens can be allowed in this flow as the RP can be authenticated.

The flow happens as follows.

  1. Client (RP) prepares Authentication request containing the required parameters and send the request to the Authorization Server (OP).
  2. OP authenticates the End-User and obtains the End-User consent if necessary.
  3. OP sends the Authorization Code to the RP.
  4. RP sends a request containing the Authorization Code to the token Endpoint of OP.
  5. OP validates the code and responds with an Access Token and ID Token to the RP.
  6. Finally, the RP decodes and validates the ID Token and retrieves the End-User’s information.

Implicit Flow

response_type = id_token

response_type = id_token token

This is the simplest flow to implement. In this flow, explicit client authentication does not take place. That means, there is only one round trip to the OP instead of two in the previous flow; all tokens are issued by the Authorization Endpoint and the Token Endpoint is not used. No Authorization Codes are generated. For this flow to occur, either id_token or id_token token has to be the value of response_type. If the value is id_token, only an ID Token is issued to the RP. If the value is id_token token, both an Access Token and an ID token are issued to the RP. As no client secret is used, Long-lived Access Tokens nor Refresh Tokens should be allowed in this flow due to security reasons.

The flow happens as follows.

  1. Client (RP) prepares Authentication request containing the required parameters and send the request to the Authorization Server (OP).
  2. OP authenticates the End-User and obtains the End-User consent if necessary.
  3. OP issues an ID Token or an Access Token and ID Token depending on the reponse_type value.
  4. RP decodes and validates the ID Token and retrieves the End-User’s information.

Hybrid Flow

response_type = code token

response_type = code id_token

response_type = code id_token token

This flow is a combination of the two former flows. This flow allows the client to obtain a token and an Authorization Code in one round trip to the OP. In the second round trip, the Authorization Code can be used to obtain the remaining token from the OP. The tokens received per round trip depends on the response_type as mentioned in the following table. In the event of the response_type being code token, open id must be included in the scope of the request as well.

The RPs using Hybrid flow must be able to maintain a unique secret as well. Due to this, Long-lived Access Tokens are allowed to be used in this flow.

The steps of the flow are explained below.

  1. Client (RP) prepares Authentication request containing the required parameters and send the request to the Authorization Server (OP).
  2. OP authenticates the End-User and obtains the End-User consent if necessary.
  3. OP sends an Authorization Code back to the RP along with a Token depending on the response_type value.
  4. RP sends a request containing the Authorization Code to the token Endpoint of OP.
  5. OP validates the code and sends both an Access Token and an ID Token to the RP.
  6. RP decodes and validates the ID Token and retrieves the End-User’s information.

More information on these flows are available here.

For more diagrams of OIDC flows, click here.

“Talent is a pursued interest. Anything that you’re willing to practice, you can do.”