Use Case

Assume you have a great idea for creating a app which will be accessed by thousands or millions of users.
At some point in their experience, you'll need to known who the user is in order to :
  1. personalize their experience
  2. offer more features
  3. ...
So how do you answer the question Who is the user?
You can build a login flow yourself and ask the user for his username and password.
  1. Is this really the core value added of your app?
  2. What do you do if your user (or employee) uses 5 or 10 applications. Do you create a login flow for each?
One approach is to give the responsibility of answering the question (Who is the user?) to someone else. The someone else is called an Identity Provider.
You have experienced this with the Login with Google, Login with Facebook, ... buttons which are available around the web (The buttons can do more, you can read more on the oAuth2 section)
So how do you ask the Identity Provider to answer the Who is the user? question?
Enters OpenID Connect.
OpenID Connect is a set of specifications which will help you communicate with the identity provider. These specifications standardize how you communicate with the identity provider so that you don't have to learn the Facebook way, the Google way or the CYM-Identity way.
From the OpenID website:
  1. OpenID Connect Core – 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
  2. OpenID Connect Discovery – Defines how clients dynamically discover information about OpenID Providers
  3. OpenID Connect Dynamic Registration – Defines how clients dynamically register with OpenID Providers

Terminology

In OpenID Connect, there are 3 parties which work together
  1. Relying Party : This is the app the user is trying to access and which needs to know Who is the user?. A Relying Party is an oAuth2 client and can be a classic web app, a Single Page app, an Android or iOS app, an IoT device, ...
  2. End User : The actual user (a human and not a machine) who will identify herself
  3. OpenID Provider : This is the system which will interact with the End User in order to answer the question Who is the user?
Since OpenID Connect builds on top of oAuth2, most of the terminology from oAuth2 applies

How does it work

Usually there are 4 steps :
  1. Client Registration: Register a Relying Party / Client (your app) with the OpenID Provider, this is where you start building the trust between your app and the OpenID Provider. This is a one time setup.
  2. OpenID Provider Metadata: Get the OpenID Provider information (the different endpoints to be used)
  3. Authentication Request: Your app asks the question Who is the user? to the OpenID Provider
  4. Authentication Response: Process the response from the OpenID Provider

Client Registration

The registration can be done manually by an admin or can be done by the developer using the OpenID Dynamic Client Registration.
At the end of the registration, the OpenID provider knows you app and you receive back :
  1. client_id this is a unique identifier for you app - think of it as a username for your app. This is how the OpenID Provider knows that it's your app, and not another app.
  2. client_secret think of it as the password for your app. This is how you'll prove you own the app to the OpenID Provider. Depending on your app, you may not receive a client_secret.

OpenID Provider Metadata

In OpenID Connect, a provider exposes multiple endpoints which are used for different tasks.
The OpenID Provider admin can either provide you these endpoints through its documentation or exposes them through OpenID Connect Discovery. This is one URL where you can find all the relevant information about the OpenID Provider.
The OpenID Connect Discovery offers a better and easier maintanability for your app developers and for the OpenID Provider admin

Authentication Request

OpenID builds on top of oAuth2's authorization request, which means that the user's browser is redirected to the OpenID Provider authorization_endpoint when you make an authentication request.
The simplest request is constructed as follows :
https://openid.provider/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=https://your.awesome.app/callback&
scope=openid%20profile&
state=STATE_OF_YOUR_APP
In details :
ElementDescription
https://openid.provider/authorizeThe authorization_endpoint of the OpenID Provider
response_typeTells the OpenID Provider what kind of response you expect. OpenID Connect has multiple response_types (code, token id_token, id_token, ...)
client_idthe unique identifier of your application
redirect_uriA URL you have registered with OpenID Provider where the user will be redirected after the authentication. Keep in mind that the authentication could fail
scopeRepresents what kind of access you need from the user. openid asks the OpenID Provider to give you back an identifier for the user. OpenID Connect defines a few other scopes : profile, email, address & phone
stateA string that your app creates which the OpenID Provider will return in the response.

Authentication Response

Once the OpenID Provider has the answer for the question Who is the user?, It'll reidrect the user back to your application using the redirect_uri from the authentication request.
The redirect looks like the following :
https://your.awesome.app/callback?
code=SOME_VALUE_THAT_DOES_NOT_MAKE_SENSE&
state=STATE_OF_YOUR_APP
In this example, the OpenID Provider does not return an explicit answer to your app, but instead it returns an intermediate response - the code. OpenID Providers are not the most straightforward talkers, but this is the most secure way of communication.
You need to exchange this code for the actual answer you have been looking for since the beginning. You'll call again the OpenID Provider token_endpoint with the following request
POST /token_endpoint HTTP/1.1
Host: openid.provider
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=SOME_VALUE_THAT_DOES_NOT_MAKE_SENSE
&redirect_uri=https%3A%2F%2Fyour.awesome.app%2Fcallback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
The OpenID Provider will finally respond with the following information
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL29wZW5pZC5wcm92aWRlciIsImF1ZCI6IllPVVJfQ0xJRU5UX0lEIiwiaWF0IjoxNTk5MjEyNTI0LCJuYmYiOjE1OTkyMTI1MjQsImV4cCI6MTU5OTIxNjUyNCwic3ViIjoiamFuZS5kb2UuMjEzNDU2Nzc4MSIsIm5hbWUiOiJKYW5lIERvZSIsImdpdmVuX25hbWUiOiJKYW5lIiwiZmFtaWx5X25hbWUiOiJEb2UiLCJwcm9maWxlIjoiaHR0cHM6Ly9vcGVuaWQucHJvdmlkZXIvdXNlcnMvamQuMzI0NTQzNTQifQ.VOFxpTNxwwXpnd7zBiw5YcNjc2SvbGhFUmXcrgnDxrk",
"access_token": "AN_ACCESS_TOKEN_VALUE",
"token_type": "Bearer",
"expires_in": 3600,
}

The id_token

From an OpenID Connect perspective, the important information from the response above is the id_token.
The id_token is the answer to the question Who is the user?. This token may look an alien language, but it has a standardized format : JWT.
You can use a website like jwt.io to read what is inside the id_token
{
"iss": "https://openid.provider",
"aud": "YOUR_CLIENT_ID",
"iat": 1599212524,
"nbf": 1599212524,
"exp": 1599216524,
"sub": "jane.doe.2134567781",
"name": "Jane Doe",
"given_name": "Jane",
"family_name": "Doe",
"profile": "https://openid.provider/users/jd.32454354"
}
You can think of this id_token as a copy of the ID Card of the user. It tells you who is the user (sub), who issued the information (iss), when it was created (iat) and it gives you some details about the End User (name, given_name, ...)

Conclusion

It may look like a lot is done just to answer a simple question, but keep in mind that your app trusts the OpenID Provider and this trust must be secured. All of the steps are meant to secure your app and protect the end user personal information.
If you look closely, in none of the steps did we mention how the OpenID Provider authenticated the user, did it use an email and password, a fingerprint or even a telepathic superpower, ... OpenID Connect focuses on the communication between your app and the OpenID Provider