Claude
Skills
Sign in
Back

oauth-oidc-protocols

Included with Lifetime
$97 forever

OAuth 2.0 and OpenID Connect protocol fundamentals including authorization code flow with PKCE, client credentials, refresh tokens, discovery documents, JWKS, and token introspection. Protocol-level troubleshooting and compliance.

General

What this skill does


# OAuth 2.0 & OpenID Connect Protocols

## When to Use This Skill

Use this skill when:
- Choosing the correct OAuth 2.0 grant type for a scenario
- Debugging token exchange flows or redirect-based authentication
- Understanding what claims and headers appear in identity tokens vs access tokens
- Implementing or troubleshooting PKCE (Proof Key for Code Exchange)
- Working with discovery documents, JWKS endpoints, or token introspection
- Reviewing security properties of different protocol flows
- Implementing refresh token rotation or token revocation

## Core Principles

1. **OAuth 2.0 is for Authorization, OIDC is for Authentication** — OAuth alone does not tell you *who* the user is. OpenID Connect adds an identity layer (the ID token) on top of OAuth.
2. **Authorization Code + PKCE is the Universal Flow** — Use it for web apps, SPAs (via BFF), native apps, and any interactive scenario. It replaced implicit flow.
3. **Tokens are Opaque to Clients** — Clients should not parse access tokens. Only the resource server (API) validates access tokens. Clients use the ID token for authentication.
4. **Discovery Documents are the Source of Truth** — Always resolve endpoints from `/.well-known/openid-configuration` rather than hardcoding URLs.
5. **Refresh Tokens Require Secure Storage** — Refresh tokens are long-lived credentials. Rotate them on every use (`OneTimeOnly`) and store them server-side.

## Related Skills

- `identityserver-configuration` — Server-side configuration of clients, resources, and scopes
- `aspnetcore-authentication` — Implementing OIDC authentication in ASP.NET Core apps
- `token-management` — Automated token lifecycle with Duende.AccessTokenManagement
- `identity-security-hardening` — Security hardening including DPoP, PAR, and FAPI
- `duende-bff` — Backend-for-Frontend pattern for SPAs

Docs: https://docs.duendesoftware.com/identityserver/fundamentals

---

## Concept 1: The OAuth 2.0 / OIDC Mental Model

### Roles

| Role | OAuth 2.0 Term | OIDC Term | Example |
|------|---------------|-----------|---------|
| User | Resource Owner | End-User | A person logging in |
| Browser/App | Client | Relying Party (RP) | ASP.NET Core web app |
| Token Server | Authorization Server | OpenID Provider (OP) | Duende IdentityServer |
| API | Resource Server | — | ASP.NET Core Web API |

### Tokens

| Token | Purpose | Who Consumes It | Format |
|-------|---------|----------------|--------|
| **ID Token** | Proves user identity | Client application | Always JWT |
| **Access Token** | Authorizes API calls | Resource server (API) | JWT or reference |
| **Refresh Token** | Obtains new access tokens | Client application | Opaque handle |

> **Critical Rule:** Clients authenticate users with the **ID token**. Clients authorize API calls with the **access token**. Never use an access token to determine who a user is. Never send an ID token to an API.

---

## Concept 2: Grant Types (Flows)

### Authorization Code + PKCE (Recommended for All Interactive Scenarios)

The authorization code flow with PKCE is the recommended flow for all clients that involve a user. PKCE prevents authorization code interception attacks.

**How it works:**

1. Client generates a random `code_verifier` and its SHA256 hash `code_challenge`
2. Client redirects user to the authorize endpoint with `code_challenge`
3. User authenticates at IdentityServer and consents (if required)
4. IdentityServer redirects back with an authorization `code`
5. Client exchanges the `code` + `code_verifier` at the token endpoint
6. IdentityServer verifies the verifier matches the original challenge
7. IdentityServer returns ID token + access token (+ refresh token if `offline_access` scope)

```
┌──────┐          ┌──────────┐          ┌──────────────┐
│Client│          │  Browser  │          │IdentityServer│
└──┬───┘          └────┬─────┘          └──────┬───────┘
   │  1. Generate PKCE │                       │
   │  code_verifier    │                       │
   │  code_challenge   │                       │
   │                   │                       │
   │  2. Redirect ───────────────────────────► │
   │     /authorize?code_challenge=...         │
   │                   │  3. User logs in      │
   │                   │  ◄──────────────────► │
   │                   │                       │
   │  4. Redirect back ◄────────────────────── │
   │     ?code=abc123  │                       │
   │                   │                       │
   │  5. POST /token ─────────────────────────►│
   │     code=abc123&code_verifier=...         │
   │                   │                       │
   │  6. Tokens ◄──────────────────────────────│
   │     { id_token, access_token,             │
   │       refresh_token }                     │
   └───────────────────┴───────────────────────┘
```

**When to use:** Web applications, native apps, SPAs (via BFF pattern).

### Client Credentials

For machine-to-machine communication with no user involvement.

```
┌──────────┐                    ┌──────────────┐
│  Service  │                    │IdentityServer│
└────┬─────┘                    └──────┬───────┘
     │  POST /token                    │
     │  grant_type=client_credentials  │
     │  client_id=...                  │
     │  client_secret=...              │
     │  scope=api1                     │
     │  ───────────────────────────►   │
     │                                 │
     │  { access_token }               │
     │  ◄───────────────────────────   │
     └─────────────────────────────────┘
```

**When to use:** Background services, daemons, server-to-server API calls.

**Key difference:** No user identity — the access token contains only client claims, not user claims.

### Refresh Token Exchange

```
┌──────┐                         ┌──────────────┐
│Client│                         │IdentityServer│
└──┬───┘                         └──────┬───────┘
   │  POST /token                       │
   │  grant_type=refresh_token          │
   │  refresh_token=old_rt              │
   │  ─────────────────────────────►    │
   │                                    │
   │  { access_token,                   │
   │    refresh_token: new_rt }         │
   │  ◄─────────────────────────────    │
   └────────────────────────────────────┘
```

> With `RefreshTokenUsage = OneTimeOnly`, each refresh returns a **new** refresh token. The old one is invalidated. This enables **refresh token rotation**, a key security measure. Note: the default changed to `ReUse` in IdentityServer v7.0 — set `OneTimeOnly` explicitly for rotation.

### Deprecated / Discouraged Flows

| Flow | Status | Why |
|------|--------|-----|
| Implicit (`token` / `id_token`) | **Deprecated** | Tokens in URL fragments; no PKCE protection |
| Resource Owner Password (ROPC) | **Discouraged** | Client handles credentials directly; no MFA support |
| Hybrid | **Replaced** | Use Authorization Code + PKCE instead |

---

## Concept 3: Discovery and JWKS

### Discovery Document

Every OpenID Connect provider publishes a discovery document at `/.well-known/openid-configuration`. This JSON document advertises:

- Endpoint URLs (authorize, token, userinfo, introspection, revocation, end\_session)
- Supported grant types, scopes, claims, and response types
- Signing algorithms and JWKS URI
- Token endpoint authentication methods

```csharp
// ✅ Use IdentityModel to fetch discovery programmatically
using var httpClient = new HttpClient();
var disco = await httpClient.GetDiscoveryDocumentAsync("https://identity.example.com");

if (disco.IsError) throw new Exception(disco.Error);

var tokenEndpoint = disco.TokenEndpoint;
var jwksUri = disco.JwksUri;
```

> **Best Practice:** Never hardcode endpoint URLs. Always resolve them from the discovery document. This ensures your application adapts to URL changes and load balancer configurations.

### JWKS (JSON Web Key Set)

The JWKS endpoint (advertised via the `jwks_uri` field in the discovery document; in Duende Iden

Related in General