Hitchhiker’s Guide to OIDC

Christoph Bühler

von

November 2022~7 Minuten

Sometimes people say: “Security is hard”. And they are - partially - right. It is hard to understand each concept in the vast space of security. It is also hard to be ahead of all the wrongdoers who want to access systems they are not allowed to. So, shall we shed some light upon the topic and explain one popular part in modern web days: OIDC.


Authentication versus Authorization

OIDC stands for “OpenID Connect”. It is an open authentication framework, or in other words: it verifies if someone is who they claim to be. To understand the purpose of OIDC, we need to know about OAuth 2.0. OAuth, compared to OIDC, is an authorization framework. But what is the difference between authentication and authorization?

Authentication (OIDC)

AuthN (abbreviation for authentication) is the process that verifies if a user is who they claim to be.

Authentication is the part which asks a user of an application for his password or social media login.

Authorization (OAuth 2.0)

AuthZ (abbreviation for authorization) is a security process that determines if a user has access to perform a specific action on a specific service or machine.

Authorization is the part that defines the access rights on a particular system for an authenticated user.

Most of the time, these two mechanisms work in harmony and are used in combination. Whether you use your social login to get access to your Twitter feed, or if you login into your Netflix account on your Smart TV.

It all started with OAuth 1.0, which was defined by RFC5849 [1]. However, to make the security concept of OAuth more feasible for the public, OAuth 2.0 was created and defined in RFC6749 [2]. OAuth 1.0 required some deep knowledge about crypto security and was a challenge to implement.

OAuth is an open authorization framework that defines how access is granted from a user to a specific system. However, it does not define how credentials (for example a username/password combination) are transmitted or verified [2].

OIDC was created to complement OAuth by defining the authentication flows. OIDC itself is not defined by an RFC but has its own specification by the OIDF (OpenID Foundation) [3].

So, to summarize: OIDC is authentication (identity verification), while OAuth represents authorization (access management).

OIDC Authentication Flows

Since OAuth does not define how the users’ credentials are transmitted, OIDC introduces several authentication flows that can be used in a secure way. All these flows use HTTPS (TLS) secured data traffic. Not all the defined authentication flows will make it to the next iteration of OAuth (OAuth 2.1). There exist some (like the “password grant”) that are deprecated because of security concerns.

The following sections will describe the three mainly used grants (“grant” in the OIDC/OAuth world means “authentication flow”) that you will likely encounter and some basic terminology.

In general, the OIDC spec [3] explains the authentication flows in a more detailed manner.

Terminology

Every topic in computer science has its own special words for certain elements. OAuth and OIDC are no exception. To understand the following sections and the diagrams, here are a few explanations about the terminology:

  • Identity Provider (IdP): An external system that contains the users’ account and has information about the login credentials and other security mechanisms.
  • Relying Party (RP): Some system (e.g., an application or an API) that requires end-user authentication or wants to access the users’ account.
  • Client or User-Agent: The original application that acts on behalf of the user.
[object Object]
Interaction between Client, Relying Party, and Identity Provider

The situation depicted in the image above shows the situation if your client (or application) is a single page application (SPA). The user accesses the SPA via some browser and somehow gets an access token from the IdP. This token is then presented to the relying party to access its API. The RP will then verify the access token with the IdP.

If the user accesses a static web-application (not an SPA), the client and relying party are merged. The client is then delivered to the user by the relying party. However, the general flow of the authentication has not changed.

Authorization Code Flow

The most popular among the “grants” is the authorization code flow. It is used for - but not exclusively - single page applications, web applications, and native applications (iOS / Android).

OIDC Authorization Code Flow with a single page application as client

The diagram above shows the authorization code flow in OIDC with a single page application.

The user (”Alice”) accesses some application (”Client”). When the user clicks “login”, she will be redirected to the IdP to enter the login credentials and possible two-factor authentications.

After the credentials have been validated by the IdP, Alice is redirected to the application with a “code”. This authorization code can only ever be used once, and it is very short-lived. The code serves the purpose of authorizing the client. Without this step, the authorization code could be grabbed by just any client which then in turn could act as a user of the IdP.

The client then exchanges the code with an access and an ID token (the so-called “token set”). This access token can then be sent to the API (relying party) to authenticate and authorize the user. The RP will verify the token against the IdP and allow or reject the access [3].

Device Authorization Flow

The next flow is the “device authorization” flow. This flow is commonly used for smart devices, CLIs and other devices that cannot provide a browser or do not have an accessible user interface. Typically, the user has some form of “trust” in the device (e.g., the users’ TV). This flow should not be used on public devices.

As an example, this flow can authenticate the user in the Netflix App on a Smart TV. The TV will show you some URL along with a device code. When you go to the URL in your smartphone, you must enter your login credentials and then authorize the device code. The device is then authorized and can fetch an access token on the user's behalf.

OIDC Device Authorization Flow

The picture above shows an example of the device authorization flow in OIDC/OAuth.

When the user (”Alice”) wants to login on a device (e.g., a smart TV app), the device will create an authorization request with the IdP. The device will then poll the IdP until the device is authorized or some timeout occurs.

While polling, Alice needs to access a login page by the IdP and provide her login credentials along with a device authorization code that the device has shown to her. The IdP then marks the device as authorized in the context of this user.

On the next poll, the device will receive an access token for the given user. Until the authorization is revoked, the device may access APIs with the given access token and the RP can verify that the device is authenticated and authorized to do so [3].

Client Credentials Flow

The last flow we cover is the “client credentials” flow. This flow is used for machine-to-machine communication. An example would be OAuth2.0 Introspection (RFC7662) which allows an API to verify a transmitted access token from a client. The introspection endpoint (an url of the IdP that is used for OAuth introspection) of an IdP returns active: true or active: false along with other information for a received access token [4]. To authenticate the API against the IdP, a client credentials flow is required to allow the API to access this information.

OIDC Client Credentials Flow

The diagram above shows an example of a client credentials flow. Two APIs want to communicate with each other. The first API (”GoLang API”) authenticates itself against the IdP with some previously known client credentials. These credentials may come in many formats. Common formats are ClientID/ClientSecret (HTTP-Basic) combination or a JWT profile.

In the case of a JWT profile [5], the first API creates a signed JWT (JSON Web Token) [6] and sends it to the IdP. The IdP then checks the used private RSA key with the stored public key. If they match, the machine is authorized.

When the machine receives the access token, it can use it to call the second API (”.NET API”) with the access token. The .NET API then verifies the access token with the IdP and returns data if the GoLang API is authorized [3].

Conclusion

Even if OIDC is not the ultimate answer to security questions (hint: the answer is 42), it does provide a secure way to authenticate users in modern applications. It does not matter if the apps are hosted on some webserver, your TV, or if the application is a mobile game. OIDC in combination with OAuth does cover these cases.

One does not simply implement the IdP by themselves. There exist companies that provide an IdP for you (e.g., ZITADEL or KeyCloak). So, instead of implementing username/password magic on your own, hook up with an IdP and let them do the heavy lifting of securing the user data.

Bibliography

  1. E. Hammer-Lahav, “The OAuth 1.0 Protocol,” Internet Engineering Task Force IETF, Apr. 01, 2010. https://www.rfc-editor.org/rfc/rfc5849 (accessed Oct. 26, 2022).
  2. D. Hardt, “The OAuth 2.0 Authorization Framework,” Internet Engineering Task Force IETF, Oct. 2012. https://www.rfc-editor.org/rfc/rfc6749 (accessed Oct. 26, 2022).
  3. N. Sakimura, J. Bradley, M. Jones, B. De Medeiros, and C. Mortimore, “OpenID Connect Core 1.0,” The OpenID Foundation OIDF, Nov. 08, 2014. https://openid.net/specs/openid-connect-core-1_0.html (accessed Oct. 26, 2022).
  4. J. Richer, “OAuth 2.0 Token Introspection,” Internet Engineering Task Force IETF, Oct. 01, 2015. https://www.rfc-editor.org/rfc/rfc7662 (accessed Oct. 26, 2022).
  5. M. Jones, B. Campbell, and C. Mortimore, “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants,” Internet Engineering Task Force IETF, May 01, 2015. https://www.rfc-editor.org/rfc/rfc7523 (accessed Oct. 26, 2022).
  6. M. Jones, J. Bradley, and N. Sakimura, “JSON Web Token (JWT),” Internet Engineering Task Force IETF, May 2015. https://www.rfc-editor.org/rfc/rfc7519 (accessed Oct. 26, 2022).