OpenID Connect
What is OIDC?
OpenID Connect (OIDC) is an identity layer built on top of OAuth 2.0.
- OAuth 2.0 → Authorization framework (access delegation)
- OIDC → Authentication protocol (who the user is)
OIDC adds:
- ID Token (JWT) — proof of authentication
- Standardised claims
- UserInfo endpoint
- Discovery document
- Standard flows
Core Concepts
| Term | Meaning |
|---|---|
| Authorization Server (AS) | Issues tokens |
| Identity Provider (IdP) | Authenticates user |
| Client | App requesting authentication |
| Resource Server (API) | Validates access token |
| ID Token | JWT proving authentication |
| Access Token | Used to call APIs |
| Refresh Token | Used to obtain new tokens |
Most Important OIDC Flow: Authorization Code Flow (with PKCE)
This is the modern recommended flow for:
- Web apps
- SPAs
- Mobile apps
- Blazor apps
- Backend APIs
High-Level Flow Overview
sequenceDiagram
participant User
participant ClientApp
participant IdP
participant API
User->>ClientApp: Access protected page
ClientApp->>IdP: Redirect to /authorize
IdP->>User: Login screen
User->>IdP: Credentials
IdP->>ClientApp: Redirect with code
ClientApp->>IdP: Exchange code for tokens
IdP->>ClientApp: ID Token + Access Token
ClientApp->>API: Call API with Access Token
Step-by-Step Breakdown (Authorization Code + PKCE)
Step 1 — Redirect to Authorization Endpoint
Client sends user to:
https://identityserver.com/authorize?
response_type=code
&client_id=app123
&redirect_uri=https://app.com/callback
&scope=openid profile api
&state=xyz
&code_challenge=abc123
&code_challenge_method=S256
Important Parameters
| Parameter | Purpose |
|---|---|
| response_type=code | Use authorization code flow |
| scope=openid | REQUIRED for OIDC |
| state | CSRF protection |
| code_challenge | PKCE security |
| code_challenge_method=S256 | Required for public clients |
Step 2 — User Logs In
The IdP:
- Authenticates user
- Creates session
- Redirects back with code
https://app.com/callback?code=AUTH_CODE&state=xyz
Step 3 — Token Exchange
Client POSTs to /token endpoint:
POST /token
grant_type=authorization_code
code=AUTH_CODE
redirect_uri=https://app.com/callback
code_verifier=original_random_value
Step 4 — Tokens Returned
{
"id_token": "eyJhbGciOiJSUzI1NiIs...",
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"expires_in": 3600,
"refresh_token": "def50200..."
}
ID Token Explained
The ID Token is a JWT containing authentication claims:
{
"iss": "https://identityserver.com",
"sub": "123456",
"aud": "app123",
"exp": 1710000000,
"iat": 1709990000,
"email": "user@example.com",
"name": "John Smith"
}
Important Claims
| Claim | Meaning |
|---|---|
| iss | Issuer |
| sub | Subject (user ID) |
| aud | Audience (client id) |
| exp | Expiry |
| nonce | Replay protection |
Why PKCE Matters
PKCE (Proof Key for Code Exchange) prevents:
- Authorization code interception
- Malicious app stealing the code
Without PKCE:
- Attacker steals
code - Exchanges it for tokens
With PKCE:
- Attacker does not know
code_verifier - Token exchange fails
Other OIDC Flows (Modern vs Legacy)
| Flow | Status |
|---|---|
| Authorization Code + PKCE | ✅ Recommended |
| Implicit Flow | ❌ Deprecated |
| Hybrid Flow | ⚠ Rare |
| Device Code Flow | ✅ Used for CLI / IoT |
| Client Credentials | OAuth only (no user) |
How OIDC Works in ASP.NET Core (.NET 8/9/10)
Setup in Web App
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://identityserver.com";
options.ClientId = "app123";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("api");
});
How APIs Validate Tokens
builder.Services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://identityserver.com";
options.Audience = "api";
});
API validates:
- Signature
- Issuer
- Audience
- Expiry
OIDC vs OAuth 2.0
| Feature | OAuth | OIDC |
|---|---|---|
| Authentication | ❌ | ✅ |
| ID Token | ❌ | ✅ |
| User Info | ❌ | ✅ |
| Standard Claims | ❌ | ✅ |
Think:
OAuth = "Can this app access the API?"
OIDC = "Who is the user?"
Real-World Providers
- Azure AD / Entra ID
- Auth0
- Okta
- Keycloak
- IdentityServer
- Google Identity
Security Considerations
Always
- Use Authorization Code + PKCE
- Validate state parameter
- Validate nonce
- Use HTTPS
- Validate JWT signature
- Use short-lived access tokens
- Store refresh tokens securely
Typical Architecture in Enterprise
flowchart LR
SPA -->|OIDC| IdP
SPA -->|Access Token| API
API --> DB
Or:
flowchart LR
WebApp -->|OIDC| IdP
WebApp -->|Access Token| API
Common Questions
Q: Why not use OAuth alone?
Because OAuth doesn't guarantee authentication identity.
Q: What is the difference between ID token and Access token?
ID token = identity
Access token = API access
Q: Why is Implicit Flow deprecated?
Tokens exposed in browser fragment → security risk.
Q: What protects against CSRF?
state parameter.
Q: What protects against replay?
nonce.
Advantages of OIDC
- Standardised authentication
- JWT-based
- Cross-platform
- Federated identity support
- Works with SSO
- Integrates well with .NET and Azure
Disadvantages / Complexity
- Many moving parts
- Token lifecycle management
- Refresh token storage risks
- Misconfiguration is common
When to Use OIDC
Use OIDC when:
- You need authentication
- You support SSO
- You support federation
- You integrate with Azure AD / Entra
- You build SPA + API architecture
Do NOT use OIDC for
- Machine-to-machine (use client credentials)
Enterprise Mental Model
Think of OIDC as:
Authentication Protocol
+ Token issuance
+ Identity standardisation
+ Federation support
In modern cloud-native systems:
OIDC is the standard authentication layer.
Summary
OpenID Connect (OIDC) is an identity protocol built on OAuth 2.0 that adds authentication capabilities via an ID token (JWT). The recommended flow is Authorization Code with PKCE, which prevents code interception attacks. The client redirects users to the identity provider, receives an authorization code, exchanges it for tokens, and validates the ID token. OIDC supports SSO, federation, and is widely implemented in ASP.NET Core via AddOpenIdConnect and JWT bearer authentication.
Further Reading
- https://openid.net/specs/openid-connect-core-1_0.html
- Microsoft Docs: ASP.NET Core authentication
- RFC 7636 (PKCE)
- OAuth 2.0 RFC 6749