> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# OIDC

> OpenID Connect authentication middleware for identity provider integration.

## Overview

The `oidc` middleware provides OpenID Connect authentication, extending OAuth 2.0 with standardized identity tokens and user information endpoints.

Use it when you need:

* Enterprise SSO integration
* Standardized identity claims
* ID token validation

## Installation

```go theme={null}
import "github.com/go-mizu/mizu/middlewares/oidc"
```

## Quick Start

```go theme={null}
app := mizu.New()

// Configure OIDC provider
provider, _ := oidc.NewProvider("https://accounts.google.com")

config := oidc.Config{
    Provider:     provider,
    ClientID:     "your-client-id",
    ClientSecret: "your-client-secret",
    RedirectURL:  "http://localhost:3000/callback",
    Scopes:       []string{"openid", "email", "profile"},
}

app.Get("/login", oidc.Login(config))
app.Get("/callback", oidc.Callback(config, handleUser))
```

## Configuration

### Config

| Field | Type | Description |
| - | - | - |
| `Provider` | `*Provider` | OIDC provider |
| `ClientID` | `string` | Client ID |
| `ClientSecret` | `string` | Client secret |
| `RedirectURL` | `string` | Callback URL |
| `Scopes` | `[]string` | Requested scopes |

## Examples

### Google OIDC

```go theme={null}
provider, _ := oidc.NewProvider("https://accounts.google.com")

config := oidc.Config{
    Provider:     provider,
    ClientID:     os.Getenv("GOOGLE_CLIENT_ID"),
    ClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"),
    RedirectURL:  "http://localhost:3000/auth/callback",
    Scopes:       []string{"openid", "email", "profile"},
}

app.Get("/auth/login", oidc.Login(config))
app.Get("/auth/callback", oidc.Callback(config, func(c *mizu.Ctx, claims *oidc.Claims) error {
    // claims.Subject - User ID
    // claims.Email - User email
    // claims.Name - User name
    return c.Redirect(302, "/dashboard")
}))
```

### Auth0

```go theme={null}
provider, _ := oidc.NewProvider("https://your-tenant.auth0.com/")

config := oidc.Config{
    Provider:     provider,
    ClientID:     os.Getenv("AUTH0_CLIENT_ID"),
    ClientSecret: os.Getenv("AUTH0_CLIENT_SECRET"),
    RedirectURL:  "http://localhost:3000/callback",
    Scopes:       []string{"openid", "email", "profile"},
}
```

### Keycloak

```go theme={null}
provider, _ := oidc.NewProvider("https://keycloak.example.com/realms/myrealm")

config := oidc.Config{
    Provider:     provider,
    ClientID:     "my-app",
    ClientSecret: os.Getenv("KEYCLOAK_SECRET"),
    RedirectURL:  "http://localhost:3000/callback",
    Scopes:       []string{"openid", "email", "roles"},
}
```

### Token Validation Middleware

```go theme={null}
verifier := oidc.NewVerifier(provider, oidc.VerifierConfig{
    ClientID: "your-client-id",
})

// Protect routes with ID token
app.Use(oidc.Verify(verifier))

app.Get("/api/me", func(c *mizu.Ctx) error {
    claims := oidc.GetClaims(c)
    return c.JSON(200, claims)
})
```

## API Reference

### Functions

```go theme={null}
// NewProvider creates OIDC provider from issuer URL
func NewProvider(issuer string) (*Provider, error)

// Login starts OIDC flow
func Login(config Config) mizu.Handler

// Callback handles OIDC callback
func Callback(config Config, handler func(*mizu.Ctx, *Claims) error) mizu.Handler

// Verify creates ID token verification middleware
func Verify(verifier *Verifier) mizu.Middleware

// GetClaims returns claims from context
func GetClaims(c *mizu.Ctx) *Claims
```

### Standard Claims

```go theme={null}
type Claims struct {
    Subject           string   // sub
    Issuer            string   // iss
    Audience          []string // aud
    Email             string   // email
    EmailVerified     bool     // email_verified
    Name              string   // name
    PreferredUsername string   // preferred_username
    Picture           string   // picture
    ExpiresAt         time.Time
}
```

## Technical Details

### Token Verification Process

The OIDC middleware implements a comprehensive JWT token verification process:

1. **Token Extraction**: Tokens are extracted from the `Authorization` header using the Bearer scheme by default. A custom `TokenExtractor` function can be provided for alternative extraction methods (e.g., from query parameters or cookies).

2. **Token Structure Validation**: The token is split into three parts (header, payload, signature) and validated for correct JWT format.

3. **Header Decoding**: The JWT header is decoded to extract the algorithm (`alg`), key ID (`kid`), and token type (`typ`).

4. **Claims Decoding**: The payload is decoded into standard OIDC claims including issuer, subject, audience, expiration, and custom claims.

5. **Validation Checks**:
   * **Issuer Validation**: Verifies the token was issued by the expected OIDC provider
   * **Audience Validation**: Ensures the token is intended for this application (supports both string and array audiences)
   * **Expiration Check**: Validates the token has not expired using the `exp` claim
   * **Not Before Check**: Validates the token is valid using the `nbf` claim if present

6. **Context Storage**: Validated claims are stored in the request context for downstream handlers to access via `GetClaims()`.

### Claims Structure

The middleware supports both standard OIDC claims and custom claims:

* **Standard Claims**: `iss`, `sub`, `aud`, `exp`, `iat`, `nbf`, `email`, `name`
* **Authorization Claims**: `groups`, `roles`, `scope`
* **Raw Claims**: All claims are also stored in a `Raw` map for accessing custom provider-specific claims

### Authorization Helpers

Three specialized middleware functions provide fine-grained access control:

* **RequireGroup**: Validates the user belongs to a specific group (checks `groups` claim)
* **RequireRole**: Validates the user has a specific role (checks `roles` claim)
* **RequireScope**: Validates the token includes a specific OAuth scope (checks space-delimited `scope` claim)

### Error Handling

The middleware provides customizable error handling through the `OnError` callback:

* **Default Behavior**: Returns a 401 Unauthorized JSON response with error details
* **Custom Handler**: Can be configured to log errors, return custom responses, or redirect to login

### Path Skipping

The `SkipPaths` option allows certain routes to bypass authentication (e.g., health checks, public endpoints) while keeping the middleware globally applied.

## Best Practices

* Use OIDC discovery (/.well-known/openid-configuration)
* Validate ID tokens for security
* Store only necessary claims in sessions
* Implement proper logout with end\_session\_endpoint
* Configure appropriate `RefreshInterval` for JWKS key rotation
* Use `SkipPaths` for public endpoints instead of conditional middleware application
* Implement custom `OnError` handlers for security-sensitive logging
* Leverage `RequireGroup`, `RequireRole`, and `RequireScope` for authorization

## Testing

The OIDC middleware includes comprehensive test coverage for various scenarios:

| Test Case | Description | Expected Behavior |
| - | - | - |
| `TestNew` | Basic middleware initialization without token | Returns 401 Unauthorized |
| `TestWithValidToken` | Valid token with correct issuer, audience, and expiration | Returns 200 OK, claims accessible via GetClaims |
| `TestExpiredToken` | Token with expiration time in the past | Returns 401 Unauthorized |
| `TestInvalidIssuer` | Token with incorrect issuer claim | Returns 401 Unauthorized |
| `TestInvalidAudience` | Token with incorrect audience claim | Returns 401 Unauthorized |
| `TestSkipPaths` | Configured paths that bypass authentication | Skipped paths return 200 OK without token, protected paths require token |
| `TestCustomTokenExtractor` | Custom token extraction from query parameters | Successfully authenticates using token from query string |
| `TestCustomOnError` | Custom error handler configuration | Returns custom error response (403 Forbidden) |
| `TestClaimsHasAudience` | String and array audience validation | Correctly identifies audience in both string and array formats |
| `TestClaimsHasGroup` | Group membership validation | Correctly identifies user group membership |
| `TestClaimsHasRole` | Role membership validation | Correctly identifies user role membership |
| `TestRequireGroup` | Group-based authorization middleware | Allows access with required group, denies without (403 Forbidden) |
| `TestRequireScope` | Scope-based authorization middleware | Allows access with required scope, denies without (403 Forbidden) |
| `TestInvalidToken` | Malformed token format | Returns 401 Unauthorized |

## Related Middlewares

* [oauth2](/middlewares/oauth2) - OAuth 2.0 authentication
* [jwt](/middlewares/jwt) - JWT validation
* [session](/middlewares/session) - Session management


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.