Add an Identity layer to OAuth2 with the OpenID Connect Protocol

Truong Loan
swile-engineering
Published in
7 min readMay 20, 2022

To remind you, the OAuth2 protocol allows for the delegation of authorization. It allows services and applications to share their data easily with each other using an access token.

Simplified OAuth2 flow (example from the article: The OAuth2.0 protocol)

Some applications retrieve a user’s information, such as email, name or surname, in order to display a personalized welcome message, for example when the user arrives on their interface. They use the access token to authenticate the visitor and retrieve their identity information. The problem with this method is that the access token is not a proof that the user is actually logged in at that moment. It just allows the holder to be authorized to access a resource.

When the Resource Server receives a request for access, it has no way of knowing if the user is logged in or not. Especially with the notion of refresh token, which we saw in the article on OAuth2 protocol, which allows making a new access token request without the user being logged in.

The solution to this problem, and to make sure that the user is logged in, is to use an overlay to OAuth2 which will manage the authentication.

This is what the OpenID Connect Protocol (OIDC) allows us to do, and we will look at it in more detail in this article.

The OpenID Connect Protocol

OpenID Connect

OIDC is a protocol that is widely used. It allows us to add an authentication overlay to OAuth2, while giving us the possibility to do identity federation.

Identity federation allows us to centralise the identity data of a user. It allows services and applications to share information about a user. In particular, it allows the user to use several services by connecting only once to a trusted third party, thanks to Single Sign On (SSO).

Today, OpenID Connect is widely used for SSO in particular. Single Sign On, as its name suggests, allows for single sign-on. This allows users to access different services and applications using a single unique identifier, for the duration of a session.

Logins and passwords without and with Single Sign On.

There are several advantages. Avoiding the user to enter yet another password that he or she will later forget. Or offering them the possibility to access several services after a single authentication. When the user logs in for the first time, a SSO session will be added to their browser in the form of a cookie. This cookie will then allow the user to use a trusted application without having to re-enter their login details.

Single Sign On

Let’s go back to our example with our user Emma, who we saw in the article on OAuth2. Let’s imagine that Emma does not have an account on LinkedIn. Two solutions are proposed to her by LinkedIn:

  • The first is to fill in an account creation form, where she has to enter her email and a password.
  • The second solution is to use her Google account to create an account, via a “connect with Google” button. This solution will allow Emma to connect with her Google account to access the LinkedIn application in SSO. More and more services are using SSO to authenticate or create an account within their applications.

The two protocols are similar. There is one notable difference, which occurs at the time of the initialization of the first request. The OpenID Scope must be specified as soon as the OIDC protocol is used.

A small difference is when the Client (client application) receives its access token. It will also receive a Token ID, which we will look at in more detail below. There are also some differences in terminology between OAuth2 and OIDC.

New OIDC roles

The End User is our user who is going to request the connection to a service, which is our Resource Owner at OAuth2.

The Relying Party will represent the Client. It will make the request to authenticate a user and retrieve some identity attributes such as email, name or first name.

The Identity Provider is our Authorization Server, will have a new functionality for authenticating a user. It will be the referrer of information to confirm that an End User has correctly authenticated.

OpenID Connect Flow

With the OAuth2 protocol, the Client will exchange an Authorization Code for an access token in order to gain access to the user’s data. OIDC introduces a new token which is the ID Token. ID Token is provided together with the access token.

id token

The ID Token is a token that will carry the identity of the person who is connected, similar to an ID card or passport. It will also contain authentication information, attributes of the End User’s identity:

{
"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",
"email": "janedoe@example.com",
"picture": "http://example.com/janedoe/me.jpg"
}
  • issuing authority (iss): is the Identity Provider; the authority that will issue the various tokens.
  • subject (sub): unique identifier assigned to a user by the ID Provider, such as a last name.
  • audience (aud): identifies the Relaying Party for which the JWT is intended.
  • nonce: character string that protects against replay attacks, which consist of interpreting a data transmission and replaying it. The nonce is associated with a Client session that has a Token ID and will verify that it is the same entity that made the first authentication request.
  • expiry date (exp): the expiry date of the token.
  • issue date (iat): date on which the token was issued.
  • We have different user attributes, like the name or the gender. They are associated with scopes that we will see a little later.

You can add other optional attributes in the OpenID Connect Core 1.0 documentation.

JWT

The ID Token uses the JWT format. It allows the exchange of tokens between several services. It can be signed (JWS) or encrypted to add a layer of confidentiality (JWE).

The backbone of the signed JWT (JWS) is composed of three parts (the Header, the Payload and the Signature) which are base64 encoded and separated by a dot.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwic3ViIjoiMjQ4Mjg5NzYxMDAxIiwiYXVkIjoiczZCaGRSa3F0MyIsIm5vbmNlIjoibi0wUzZfV3pBMk1qIiwiZXhwIjoxMzExMjgxOTcwLCJpYXQiOjEzMTEyODA5NzAsIm5hbWUiOiJKYW5lIERvZSIsImdpdmVuX25hbWUiOiJKYW5lIiwiZmFtaWx5X25hbWUiOiJEb2UiLCJnZW5kZXIiOiJmZW1hbGUiLCJlbWFpbCI6ImphbmVkb2VAZXhhbXBsZS5jb20iLCJwaWN0dXJlIjoiaHR0cDovL2V4YW1wbGUuY29tL2phbmVkb2UvbWUuanBnIn0.a7BkqyH2bUn-_QK7XuHc1yUe3m2AhcN2_2DxLxoo37Y

The Header will provide information about the type of signature and the encryption used for the encoding.

{ "alg": "HS256", "typ": "JWT" }

The Payload is the most interesting part, it contains the information that will be transmitted to the Client.

{ "sub": "12345677", "name": "Jane Doe", "exp": 1311281970}

The signature encodes the JWT via a secret key that is known only to the token provider. It allows to verify that the token has not been modified during a request.

{ 7WK5T79u5mIzjIXXi2oI9Fglmgivv7RAJ7izyj9tUyQ }

The JWE is used when an ID Token needs to be encrypted and encoded in base64url. Both parties (the sender and the receiver of the JWE) must have the same encryption key to decode the content. The JWE is composed of 5 types, separated by dots.

  • The Header, which is used to retrieve the encoding information.
  • The Encrypted Key is the encryption key.
  • The JWE initialization vector, which allows the introduction of a random character for the encryption.
  • The JWE Ciphertext is the Payload where the identity attributes of an encrypted user will be found.
  • The JWE Authentication Tag guarantees the integrity of the ciphertext.

Identity attributes and scopes.
The OIDC protocol provides about twenty identity attributes and four scopes that can be used for consent and for retrieving information about the End User.

OIDC Scopes

We have standard attributes predefined by OIDC:

  • Scope profile: last name, first name, gender, date of birth, avatar…
  • Scope email: email
  • Scope address: user’s address
  • Scope phone: telephone number

There are also private attributes that are offered by the Identity Provider.

This information is accessible in the ID Token. If the Client needs to retrieve information about the user who has just logged in, it can use the endpoint that is introduced by OIDC: UserInfo.

OpenID Connect endpoints

The UserInfo endpoint is protected by OAuth2. The Client must present a valid access token to access the identity attributes.

OIDC provides other default endpoints:

  • authorization: to allow authentication of a user
  • token: to request an access / refresh / ID token.
  • revocation: to delete an access token or a refresh token
  • introspection: to validate an access or a refresh token.

It is also possible to use an endpoint that already exists with OAuth2: Discovery endpoint. The Discovery endpoint allows access to configuration data, such as supported scopes, other endpoints or encryption algorithms.

If you liked this article, feel free to put a like and subscribe :)

--

--