Why OpenID Connect Sits on Top of OAuth 2.0
OAuth 2.0 was designed purely for delegated authorization: it lets a client obtain an access token so it can call an API on a user's behalf, but it says nothing about who the user actually is. OpenID Connect (OIDC) is a thin identity layer built on top of OAuth 2.0 that adds a standardized ID token, a UserInfo endpoint, and well-defined claims like sub, iss, aud, and exp so applications can perform authentication, not just authorization.
Cricket analogy: An access token is like a stadium gate pass that lets you enter and watch the Ashes Test, but it doesn't tell the gatekeeper whether you're Root or Kohli — OIDC's ID token is the signed scorecard that actually names the player.
The ID Token and Its Claims
The ID token is a JSON Web Token (JWT) consisting of a header, payload, and signature, and its payload carries standardized claims: iss (the issuer URL of the identity provider), sub (a stable unique subject identifier for the user), aud (the client_id the token was issued for), exp and iat (expiry and issued-at timestamps), and optionally nonce and auth_time. Unlike an opaque access token, the ID token is meant to be parsed and read by the client itself, never sent to a resource server as a bearer credential.
Cricket analogy: The sub claim is like a player's permanent BCCI registration number — Virat Kohli's identity doesn't change even if his team, jersey number, or the tournament (aud) changes each season.
The Authorization Code Flow with OIDC
To authenticate a user with OIDC, the client redirects to the authorization endpoint with scope=openid (plus optional profile and email scopes), response_type=code, a state value, and a nonce. After the user authenticates and consents, the client exchanges the returned code at the token endpoint for an access_token, an id_token, and often a refresh_token. Before trusting any claim inside the id_token, the client must validate its signature against the provider's JSON Web Key Set (JWKS), and confirm iss, aud, exp, and nonce all match expectations.
Cricket analogy: The DRS review process is a good analogy: the third umpire doesn't just accept the on-field call, they cryptographically cross-check ball-tracking and snickometer signals (the JWKS signature) before confirming the dismissal.
Always validate an ID token before trusting it: check the signature against the provider's JWKS endpoint, confirm iss matches the expected issuer, aud matches your client_id, exp hasn't passed, and (when present) nonce matches the value you originally sent. Libraries like openid-client, MSAL, or AppAuth handle this validation correctly out of the box.
UserInfo Endpoint and Discovery
Every conformant OIDC provider publishes a discovery document at /.well-known/openid-configuration listing its authorization_endpoint, token_endpoint, jwks_uri, and userinfo_endpoint, which lets clients auto-configure themselves instead of hardcoding URLs. The UserInfo endpoint accepts the access_token (not the id_token) as a bearer credential and returns additional profile claims such as name, email, and picture, scoped to whatever the client requested via the openid, profile, and email scopes.
Cricket analogy: The discovery document is like the ICC's official fixtures and venue directory — instead of guessing where the next World Cup match is, every broadcaster fetches the same authoritative schedule from one source.
A common mistake is treating the access_token as if it contains verifiable identity information, or worse, sending the id_token to a resource server as if it were a bearer token for API calls. The id_token is for the client to consume locally to establish a login session; only the access_token should ever be presented to APIs, and only the UserInfo endpoint or the id_token's own claims should be used for identity data.
- OAuth 2.0 handles authorization (access to resources); OpenID Connect adds authentication (identity) on top of it.
- The ID token is a JWT with standardized claims: iss, sub, aud, exp, iat, and optionally nonce and auth_time.
- Always validate an ID token's signature via the provider's JWKS before trusting any of its claims.
- The nonce parameter binds the authentication request to the returned ID token, preventing replay attacks.
- The discovery document at /.well-known/openid-configuration lets clients auto-configure endpoints instead of hardcoding them.
- The UserInfo endpoint takes an access_token (not an id_token) and returns additional profile claims.
- Never use an id_token as a bearer credential against an API — only access_tokens are meant for that purpose.
Practice what you learned
1. What is the primary purpose of the ID token in OpenID Connect?
2. Which claim in an ID token should be checked to prevent replay attacks in the authentication request itself?
3. Where should an ID token's signature be validated against?
4. What credential does the UserInfo endpoint expect to be presented as a bearer token?
5. What does the discovery document at /.well-known/openid-configuration typically provide?
Was this page helpful?
You May Also Like
Implementing OAuth in a Web App
A practical guide to wiring the Authorization Code flow into a server-rendered web application, from callback handling to secure token storage and refresh rotation.
OAuth for Single-Page Apps
Learn why browser-based SPAs must be treated as public OAuth clients, how PKCE secures the Authorization Code flow, and why the BFF pattern beats storing tokens in the browser.
OAuth for Mobile Apps
How native iOS and Android apps should implement OAuth 2.0 per RFC 8252: external user-agents, PKCE, claimed redirect URIs, and hardware-backed token storage.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics