Post

OAuth2 and OIDC Deep Dive: Real Flow Breakdown

Introduction

OAuth2 is an authorization framework, while OpenID Connect (OIDC) layers authentication on top of OAuth2. A correct implementation requires understanding each protocol artifact, how tokens are issued, and where validation occurs. This deep dive walks through the real flow sequence and the validation decisions that matter in production systems.

OAuth2 Roles and Artifacts

OAuth2 defines four core roles and several artifacts. Each artifact has a distinct lifecycle and security boundary.

  • Resource owner: The end user or system that grants access.
  • Client: The application requesting delegated access.
  • Authorization server: Issues access and refresh tokens.
  • Resource server: Validates access tokens and serves protected APIs.
  • Artifacts: Authorization code, access token, refresh token, and (with OIDC) ID token.

Authorization Code Flow with PKCE

Authorization Code with PKCE is the modern baseline for browser and native applications. The real flow involves multiple checks on each hop.

  1. Client generates a high-entropy code_verifier and derived code_challenge.
  2. User authenticates on the authorization server, which stores code_challenge with the authorization code.
  3. Client exchanges the code for tokens by presenting the code_verifier.
  4. Authorization server validates the code, verifies the code_verifier, and issues tokens.
  5. Resource server validates access tokens on every call.

OIDC Layer: ID Token Validation

The ID token is a signed JWT that represents the authentication event. Validation must be performed by the client that receives the token.

  • Issuer validation: Must match the expected OIDC issuer.
  • Audience validation: Must contain the client ID.
  • Signature validation: Use the current signing keys from the JWKS endpoint.
  • Nonce validation: Matches the value stored before the authorization request.
  • Temporal validation: Verify exp, iat, and clock skew.
  • Authenticated session: Confirm auth_time for max-age or step-up policies.

Refresh Tokens, Rotation, and Token Exchange

Refresh tokens provide long-lived access but require strict handling.

  • Use refresh token rotation to invalidate old refresh tokens.
  • Bind refresh tokens to device or client with sender-constrained tokens when possible.
  • Apply token exchange only when a trusted backend must call another API on behalf of a user.

C# Example: Validating an ID Token

The following C# example uses JwtSecurityTokenHandler to validate an ID token against the issuer, audience, and signing keys.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;

var issuer = "https://login.example.com";
var clientId = "web-client";
var metadataAddress = $"{issuer}/.well-known/openid-configuration";

var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
    metadataAddress,
    new OpenIdConnectConfigurationRetriever());

var oidcConfig = await configurationManager.GetConfigurationAsync();

var tokenHandler = new JwtSecurityTokenHandler();
var parameters = new TokenValidationParameters
{
    ValidIssuer = issuer,
    ValidAudience = clientId,
    IssuerSigningKeys = oidcConfig.SigningKeys,
    RequireSignedTokens = true,
    ValidateLifetime = true,
    ClockSkew = TimeSpan.FromMinutes(2)
};

var principal = tokenHandler.ValidateToken(idToken, parameters, out var validatedToken);

Hardening Checklist

  • Enforce PKCE even for confidential clients.
  • Store authorization codes server-side and make them single-use.
  • Use short access token lifetimes with rotation for refresh tokens.
  • Validate token azp when using multiple audiences.
  • Prefer sender-constrained tokens for high-risk APIs.

Conclusion

OAuth2 and OIDC succeed when every artifact is validated in the correct boundary. By treating the authorization server, client, and resource server as distinct trust zones, you avoid the common mistakes that lead to token replay, misissued tokens, and excessive privilege.

This post is licensed under CC BY 4.0 by the author.