oidcmock.dev

A mock OpenID Connect (OIDC) provider for local development and testing.

The discovery document is available at https://oidcmock.dev/.well-known/openid-configuration

Standard Authorize Request

Initiate the OIDC flow by redirecting the user to the authorization endpoint:

GET https://oidcmock.dev/oauth/authorize
  ?client_id=<your_client_id>
  &response_type=code
  &redirect_uri=<your_redirect_uri>
  &state=<your_state>
  &nonce=<your_nonce>

The client_id can be any string (there is no client registration step). The Client ID Metadata Document draft specification is supported.

Supported Response Types

  • code
  • id_token
  • token
  • code id_token
  • code token
  • token id_token
  • code id_token token

Supported Response Modes

  • query
  • fragment
  • form_post

Test Implicit Flow

You can test a standard implicit authorization flow instantly using this link:

https://oidcmock.dev/oauth/authorize?client_id=foo&response_type=id_token&redirect_uri=https://jwt.io

Pushed Authorization Requests (PAR)

PAR (RFC 9126) allows clients to push authorization parameters directly to the provider before redirecting the user. Under standard PAR, clients send standard application/x-www-form-urlencoded POST parameters (like client_id, response_type, redirect_uri, etc.) directly to the PAR endpoint. Wrapping parameters in a signed Request Object JWT (JAR) is optional but not required. The provider returns a JSON response containing a request_uri and an expiration time.

How PAR works:

  1. The client sends a POST request containing the authorization parameters to the PAR endpoint:
    POST https://oidcmock.dev/oauth/par
    Content-Type: application/x-www-form-urlencoded
    
    client_id=<your_client_id>
    &response_type=code
    &redirect_uri=<your_redirect_uri>
    &state=<your_state>
    &nonce=<your_nonce>
  2. The provider validates the parameters and returns a 201 Created JSON response containing a request_uri and an expiration time:
    {
      "request_uri": "urn:ietf:params:oauth:request_uri:req-123456",
      "expires_in": 90
    }
  3. The client redirects the user's browser using the returned request_uri and the client's client_id:
    GET https://oidcmock.dev/oauth/authorize
      ?client_id=<your_client_id>
      &request_uri=urn:ietf:params:oauth:request_uri:req-123456

JWT Secured Authorization Requests (JAR)

JAR (RFC 9101) allows passing OIDC authorization parameters securely inside a signed JWT (Request Object). This prevents query parameter tampering and secures the request. oidcmock.dev supports both **by-value** (request) and **by-reference** (request_uri) parameters.

Creating a JAR Request Object

A Request Object is a JSON Web Token (JWT) containing your authorization parameters as claims. To verify the JWT, the provider requires the JWT to be signed (using the client's private key) or unsigned (using "alg": "none").

Required JWT Claims:

  • iss (Issuer): Must be the client's client_id.
  • aud (Audience): Must be the mock provider's issuer URL:https://oidcmock.dev
  • client_id (string): Must match the iss claim and the query parameter client_id.
  • response_type (string): Must match the expected response type (e.g. code).

Optional / Recommended Claims:

  • redirect_uri (string): The client's callback URL.
  • scope (string): Typically openid profile email.
  • state (string): Anti-tampering random string.
  • nonce (string): Replay protection string.

Example Request Object JWT Structure:

Header:
  {
    "alg": "RS256",
    "typ": "JWT",
    "kid": "client-key-id"
  }

Payload:
  {
    "iss": "test-client",
    "aud": "https://oidcmock.dev",
    "client_id": "test-client",
    "response_type": "code",
    "redirect_uri": "https://localhost:3001/callback",
    "scope": "openid profile email",
    "state": "abc123state",
    "nonce": "xyz789nonce"
  }

Option A: JAR By Value (request)

Pass the signed Request Object JWT directly in the query parameters:

GET https://oidcmock.dev/oauth/authorize
  ?client_id=test-client
  &request=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6...

Option B: JAR By Reference (request_uri)

Provide a URL pointing to the hosted Request Object JWT:

GET https://oidcmock.dev/oauth/authorize
  ?client_id=test-client
  &request_uri=https://client.example.com/request-object.jwt

Signature Verification

The mock server will automatically fetch the public keys from the client's jwks_uri to verify the signature. You can configure the client's jwks_uri in the custom configurations on the authorize login screen, or have it fetched automatically by registering your client_id as a URL (using the Client ID Metadata Document protocol).

Token Endpoint & Client Authentication

Exchange the authorization code for tokens by making a POST request to the token endpoint:

POST https://oidcmock.dev/oauth/token
Content-Type: application/x-www-form-urlencoded

Supported Client Authentication Methods

1. client_secret_post

Send the client credentials directly in the POST body parameters:

grant_type=authorization_code
&code=<authorization_code>
&redirect_uri=<your_redirect_uri>
&client_id=<your_client_id>
&client_secret=test-client-secret

The default client secret is: test-client-secret

2. client_secret_basic

Authenticate using basic access authentication (Authorization Header):

Headers:
  Authorization: Basic <base64(client_id:client_secret)>

Body:
  grant_type=authorization_code
  &code=<authorization_code>
  &redirect_uri=<your_redirect_uri>

3. private_key_jwt

Authenticate the client using a signed JWT (client assertion) without sharing secrets:

Body:
  grant_type=authorization_code
  &code=<authorization_code>
  &redirect_uri=<your_redirect_uri>
  &client_id=<your_client_id>
  &client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
  &client_assertion=<client_assertion_jwt>

DPoP (Demonstrating Proof-of-Possession)

DPoP (RFC 9449) binds issued access tokens to the client's public key. This prevents token theft and replay attacks because the client must prove possession of the private key when using the token.

1. At the Token Endpoint

Send the OIDC authorization code exchange request with a DPoP header containing a DPoP Proof JWT:

Headers:
  DPoP: <DPoP_Proof_JWT>

Body:
  grant_type=authorization_code
  &code=<authorization_code>
  &redirect_uri=<your_redirect_uri>

DPoP Proof JWT Structure:

Header:
  {
    "typ": "dpop+jwt",
    "alg": "RS256",
    "jwk": { <client_public_key_jwk> }
  }

Payload:
  {
    "jti": "<unique_random_string>",
    "htm": "POST",
    "htu": "https://oidcmock.dev/oauth/token",
    "iat": 1782635400,
    "nonce": "<server_provided_nonce_if_any>"
  }

The mock server verifies the DPoP proof, calculates the key thumbprint (jkt), and embeds it in the access token under the cnf claim: "cnf": { "jkt": "<thumbprint>" }. The returned token_type will be set to DPoP.

2. At the Userinfo Endpoint

Present the bound access token and a new DPoP Proof JWT protecting the request:

Headers:
  Authorization: DPoP <access_token>
  DPoP: <New_DPoP_Proof_JWT>

New DPoP Proof JWT Payload:

{
  "jti": "<new_random_string>",
  "htm": "POST",
  "htu": "",
  "iat": 1782635400,
  "ath": "<base64url_sha256_hash_of_access_token>"
}

3. DPoP Nonce Support

You can configure DPoP Nonce enforcement on the authorize login configuration screen. If enforced (or if the client sends an invalid nonce), the server responds with a 400 Bad Request containing {"error": "use_dpop_nonce"} and includes a

Client ID Metadata Document (CIMD)

The Client ID Metadata Document draft specification allows mock/local environments to dynamically resolve OIDC client metadata without pre-registering clients.

If the client_id in the authorization request starts with http:// or https://, the server treats it as a metadata document URL and fetches it to obtain the client's configuration.

Supported Properties

  • client_id (string, required) Must match the URL used as the client ID.
  • jwks_uri (string, required) The URL of the client's public keys. Used to verify JAR Request Objects and private_key_jwt signatures.
  • token_endpoint_auth_method (string, optional) Expected client authentication method at the token endpoint (either private_key_jwt or none).
  • redirect_uris (array of strings, optional) If specified, the requested redirect URI must match one of the entries in this list.

Example Document Shape

{
  "client_id": "https://my-app.example.com/client-metadata.json",
  "client_name": "My Local Test App",
  "jwks_uri": "https://my-app.example.com/jwks.json",
  "token_endpoint_auth_method": "private_key_jwt",
  "redirect_uris": [
    "https://my-app.example.com/callback",
    "http://localhost:3000/callback"
  ]
}