Introduction
This is part five in a series of posts where I write about OAuth 2.0 & OpenID Connect. You can find the preceding articles here:
Part 0 - Terminology
Part 1 - An Introduction
Part 2 - Authorization Code Flow + PKCE
Part 3 - Client Credentials Flow
Part 4 - Device Authorization Flow
Part 5 - OpenID Connect Introduction
So far we have discussed how OAuth 2.0 allows a user to delegate authorization to a client application in a secure manner and how it solves the password anti-pattern.
However OAuth 2.0 isn't ment to authenticate users and also it doesn't tell the client anything about its user.
This is where the OpenID Connect (OIDC) protocol comes into play. It enables a client to establish a login session (authentication) and also to gain identity information about the logged in user. For example it allows a client to retrieve the users profile picture, mail address, name, and so on (if you as a data owner consent to this transaction).
OIDC can't work without the underlying OAuth 2.0 framework as it sits on top of it. We will see in a minute what is meant by this.
OpenID generations
In general there are three generations of OpenID, which can be confusing, when doing some web research.
The first generation consists of the OpenID versions 1.0 (May 2005), 1.1 (May 2006) and 2.0 (Dec 2007). The second generation was an extension to OAuth 2.0 and the third generation is called OpenID Connect (Nov 2014) which we are going talk about in this article.
Identity Federation
It's easier to pin OIDC down and understand its relation to OAuth 2.0 when we grasp the underlying concept first, which is identity federation.
Identity federation can be seen as the practice of linking a single identity across multiple disparate identity management systems.
To make the statement from above more obvious think about how many web accounts you are managing today. You might have one for WordPress, LinkedIn, Facebook, Gmail, Dropbox another one for Twitter and so on...
Managing a separate account for each of this services is tedious and we all know this mind numbing sign-up procedures we all have walked through several times.
This is where the concept of identity federation helps in that you only have to manage a single identity for several other services that have a trust relationship with your identity provider.
In the simple diagram from above, Google is acting as an OpenID Connect Provider (OP) where the surounding services (relying partys, RP) have delegated there identity management to Google. No credentials are getting stored ore managed on the clients, they trust the OPs ability to authenticate the users.
Now whats important to note here, is that the concept of Identity Federation really is just another use case for delegated authorization that we have seen in part 1 of this series.
With OAuth 2.0 the protected resource is the user data (e.g. photos), with OIDC the protected resource is the users identity information!
Identity Federation is just another use case for the concept of delegated authorization.
And this is the reason why its said that OpenID Connect sits on top of OAuth 2.0.
Authentication using the AuthZ Code Flow
Let's now have a quick look at how a client can establish a login session by leveraging the OAuth 2.0 authorization code grant that we discussed in part 2 in this series.
The flow basically consists of two steps.
- Authenticate user & receive user consent
- Authenticate client (optional) & exchange authorization code for tokens
The result of step 1 is an authorization code (acting as an input to step 2), whereas the result of step 2 is an access token and an id token.
The following diagram depicts the steps involved, when signing into LinkedIn using a linked Google identity (the URLs are exemplarily). I am not going through every step again as I have done so before in part 2.
The important difference to note here is that the requested scope in step 1.1 must be set to (at least) openid
, which informs the OpenID provider that the client is requesting and id token.
As you can see from the diagram other scopes can be requested along with openid
, like profile
or Contacts.Read
. The result of this flow is the issuance of an access_token
along with an id_token
(step 6).
ID Token
The ID token is the primary extension that OIDC makes to OAuth 2.0 to enable users to be authenticated. This id_token
is represented as a JWT and contains digitally signed information (or claims
) about a user.
This ID token is only intended to the client that whishes to receive identity information about the logged in user. Its not ment to be sent anywhere as opposed to an access token (e.g. to the resource server).
Here is an example of an ID token issued by Azure AD.
{
"typ": "JWT",
"alg": "RS256",
"kid": "1LTMzakihiRla_8z2BEJVXeWMqo"
}.{
"ver": "2.0",
"iss": "https://login.microsoftonline.com/9122040d-6c67-4c5b-b112-36a304b66dad/v2.0",
"sub": "AAAAAAAAAAAAAAAAAAAAAIkzqFVrSaSaFHy782bbtaQ",
"aud": "6cb04018-a3f5-46a7-b995-940c78f5aef3",
"exp": 1536361411,
"iat": 1536274711,
"nbf": 1536274711,
"name": "Abe Lincoln",
"preferred_username": "[email protected]",
"oid": "00000000-0000-0000-66f3-3332eca7ea81",
"tid": "9122040d-6c67-4c5b-b112-36a304b66dad",
"nonce": "123523",
"aio": "Df2UVXL1ix!lMCWMSOJBcFatzcGfvFGhjKv8q5g0x732dR5MB5BisvGQO7YWByjd8iQDLq!eGbIDakyp5mnOrcdqHeYSnltepQmRp6AIZ8jY"
}.[Signature]
OIDC Scopes & Claims
Claims are key/value pairs carrying information about the user. Whereas scopes can be seen as groups of claims. This are the scopes introduced by OIDC.
Scope | Claims contained |
---|---|
openid |
sub, iss, aud, exp, iat, at_hash |
profile |
name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, updated_at |
email |
email, email_verified |
address |
address |
phone |
phone_number, phone_number_verified |
These are the most important claims
Claim | Description |
---|---|
sub |
Subject, identifies the user |
iss |
Issuer, identifies the security token service (STS) that constructs and returns the token |
aud |
Audience, identifies the intended recipient of the token. In id_tokens, the audience is your client id |
exp |
Expires, identifies the expiration time on or after which the id token must not be accepted for processing |
iat |
Indicates when the authentication for this token occurred. |
You can find more about the claims here
Userinfo endpoint
Another extension that OIDC makes to OAuth 2.0 is a new endpoint the userinfo endpoint
.
It serves information about a user in addition to the user-information already contained in an id token.
This endpoint gets hosted by the OP and is a standard OAuth Bearer Token API, that requires an access token (not ID token!) when requested.
An ID token already covers the most important user information. Its not recommended to query the userinfo for information as long as you don't have a need for very special data. The reason is that it introduces an additional round-trip that may be avoided for performance reasons.
Key take-aways
- OIDC allows to use a single identity to log into several websites
- It enables web-based SSO
- It leverages the OAuth 2.0 grant types like AuthZ Code flow
- Introduces an ID token and a userinfo endpoint
- Identity federation is a special use case of delegated authorization
- An ID token is only intended for the client (relying party)