Skip to main content

Conceptadvanced

OpenID Connect

Overview

OpenID Connect is a thin layer on top of OAuth 2.0 that adds what was missing: a token that asserts identity.

Where OAuth delivers an access token — "the bearer may do X" — OpenID Connect also delivers an ID token: "this user, with these attributes, authenticated at this moment, and this token is for you".

The three final parts are what prevent the attacks that made OAuth inadequate for login.

Problem

Using OAuth for authentication is common and wrong, and the mistake has a concrete consequence.

The problematic pattern: the application obtains an access token, calls a profile API, receives a user identifier and considers the person authenticated.

What breaks: nothing in that flow guarantees the token was issued for that application. A token obtained by another application — including a malicious one, to which the user granted access — works just the same.

OpenID Connect solves it with a token that declares the audience and is verifiable.

Core Concepts

The ID token and the access token are different

ID token for the client — asserts who authenticated
verified by the client, never sent to the API
access token for the API — asserts permission
sent to the API, opaque to the client

Confusing them is the most common implementation mistake. Sending the ID token to the API, or trying to read the access token in the client, indicates the distinction was not understood.

The claims that need to be verified

An ID token is a signed JWT, and receiving it is not enough — it needs to be validated:

signature checks out with the issuer's public key
iss the issuer is the one you expect
aud the audience is your application — the central check
exp it has not expired
iat issued recently
nonce matches the value you sent in the request

aud is the check that prevents the attack described above. A token issued for another application has a different audience and must be rejected.

nonce prevents reuse: the client generates a random value, sends it in the authentication request, and the token comes back with it. A captured token does not work in a new session.

Skipping any of these turns the authentication into theater.

sub is the identifier, and it is local to the issuer

The sub field is the user's stable identifier — within that issuer.

Two points that cause problems:

Do not use email as the identifier. It can change, and the email_verified field exists precisely because it has not always been verified. Accepting an unverified email as identity allows somebody to register with another person's email and take over their account.

sub is only unique within the issuer. With multiple providers, the internal identity needs to be the combination of issuer and sub.

Scopes and where the attributes come from

User attributes come through scopes — openid, profile, email — and can arrive from two places: inside the ID token, or from a user info endpoint.

Putting many attributes in the token makes it large, and it travels in every authentication request. Fetching from the endpoint keeps the token small and adds a call.

The usual practice: the identifier and the minimum in the token; the rest queried when necessary.

Session termination is the hard part

Single sign-on works well. Single sign-out is where the implementations fail.

The user leaves one application — and remains authenticated in the others, because each has its own session. Worse, one click on "sign in" silently reauthenticates, because the session at the provider is still alive.

The logout specifications exist and adoption is uneven. The behavior needs to be decided explicitly: does leaving one application end the provider's session, or only the local one?

For environments with sensitive data, ending everything is what is expected — and frequently it is not what happens.

Discovery and key rotation

The provider publishes its configuration and its public keys at well-known addresses.

The client should fetch the keys and cache them with periodic refresh — because providers rotate keys. An implementation that pins the key breaks at rotation, typically overnight.

And it should look up by key identifier, not assume there is only one.

Mental Model

OpenID Connect is OAuth plus a token that says who you are and whom it was issued for. Those two assertions are what makes the authentication safe.

When to Use

  • Authentication delegated to an identity provider.
  • Single sign-on across several applications.
  • Social login for consumers.
  • Corporate federation.
  • You want to delegate authentication instead of managing credentials.

When Not to Use

For authorization. The ID token is not an API access credential.

Without verifying aud. It nullifies the main protection.

Without nonce. It allows reuse.

Accepting an unverified email as identity.

An ID token sent to the API.

A public key pinned in the code. It breaks at rotation.

When there is no user. A service talking to a service uses client credentials.

Alternatives

  • Plain OAuth 2.0 — when the need is delegated access, not identity.
  • SAML — corporate federation in environments that already use it. More verbose, very established.
  • Mutual TLS — service identity.
  • Your own session with a local credential — when there is neither federation nor third parties, and simplicity is worth more.

Trade-offs

OpenID ConnectYour own authentication
Credentials at the providerYou store them
A second factor readyTo be implemented
Single sign-onSeparate sessions
Provider dependencyAutonomy
Checks to get rightA simpler flow
Attributes in the tokenA user info endpoint
No extra callOne call
A large tokenSmall
The data can go staleAlways current

Failure Modes

aud not verified. Another application's token accepted.

nonce absent. Token reuse.

An unverified email as the key. Account takeover.

A rotated key. Validation breaks.

Partial logout. The session persists in the other applications.

The provider unavailable. Nobody signs in.

sub colliding between providers.

Common Mistakes

Not verifying every claim.

Using the ID token as an access token.

Identifying by email.

Not handling key rotation.

Not deciding the logout behavior.

Implementing the validation by hand instead of using a mature library. It has details that fail silently.

Real-World Example

An education company migrated six applications to single sign-on with OpenID Connect, using a managed provider.

The implementation was done by different teams, each on its own application. A security review six months later found inconsistencies:

Two applications did not verify aud. A token issued for the student application was accepted by the administrative application. Since the provider was the same and so were the users, a student with a legitimate account could obtain a token and present it to the administrative application — which accepted it and created a session. The subsequent authorization blocked most actions, but not all.

Three did not use nonce.

One identified by email. A student changed the email in their record to a teacher's — who had not yet accessed the system — and, on the first login, was recognized as the teacher.

None handled key rotation. All of them pinned the public key in configuration. When the provider rotated, all six stopped simultaneously at 2 a.m. on a Sunday. The incident lasted 4 hours.

Partial logout. Leaving one application did not end the others. In the institution's shared computer labs, that meant the computer's next user found open sessions.

The fixes:

A single validation library, maintained centrally, with every check. The six teams came to use it instead of each one implementing its own.

An internal identifier derived from issuer plus sub.

A key cache with periodic refresh and lookup by identifier.

Global logout configured, ending the provider's session.

The learning that stuck: six independent implementations of the same protocol produced six different sets of omissions. The decision to let each team implement — made to avoid creating a dependency — cost more than the dependency would have.

Practical Exercise

Take your system's ID token validation and check whether it verifies signature, issuer, audience, expiration and nonce.

The absence of any one is exploitable, and the absence of the audience check is the most serious.

Interview Questions

  • What is the difference between an ID token and an access token?
  • Why is verifying aud the central protection?
  • Why is identifying by email dangerous?

Further Reading

  • OpenID Connect Core 1.0 — the specification.
  • OpenID Connect Session Management and RP-Initiated Logout.
  • Wilson, Yvonne; Hingnikar, Abhishek. Solving Identity Management in Modern Applications. 2nd ed. Apress, 2022.
Finished reading this document?Your progress is saved in this browser only.