Well-Known Configuration — Complete OIDC Provider Metadata Reference
In this tutorial, you will learn about Well. We cover key concepts, practical examples, and best practices to help you master this topic.
The well-known configuration document is a JSON file at /.well-known/openid-configuration that describes every aspect of an OIDC provider's capabilities, from endpoint URLs to supported signing algorithms and claim types.
What You'll Learn
- Complete field reference for the discovery document
- Provider extensions and custom metadata
- Using the document for secure client initialization
Why It Matters
Two OIDC providers may support different features. One may support ES256 signing, another only RS256. One may support form_post response mode, another only query. The discovery document tells your client exactly what the provider supports.
Real-World Use
Before Doda Browser sends an authentication request, it checks the provider's discovery document for supported response types, scopes, and token endpoint auth methods. This prevents runtime errors from unsupported features.
flowchart LR
Config["Well-Known Config"] --> Auth["Authorization\nEndpoint"]
Config --> Token["Token\nEndpoint"]
Config --> JWKS["JWKS\nURI"]
Config --> UserInfo["UserInfo\nEndpoint"]
Config --> Scopes["Supported\nScopes"]
Config --> Algs["Supported\nAlgorithms"]
Config --> Claims["Supported\nClaims"]
style Config fill:#dbeafe,stroke:#2563eb
Complete Field Reference
config = {
# REQUIRED
"issuer": "https://provider.example.com",
"authorization_endpoint": "https://provider.example.com/auth",
"token_endpoint": "https://provider.example.com/token",
"jwks_uri": "https://provider.example.com/certs",
"response_types_supported": ["code", "id_token", "token id_token"],
"subject_types_supported": ["public", "pairwise"],
"id_token_signing_alg_values_supported": ["RS256", "ES256"],
# RECOMMENDED
"scopes_supported": ["openid", "profile", "email", "address", "phone"],
"claims_supported": ["sub", "iss", "aud", "exp", "iat", "name", "email"],
"userinfo_endpoint": "https://provider.example.com/userinfo",
"registration_endpoint": "https://provider.example.com/register",
# OPTIONAL
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post",
"private_key_jwt"
],
"grant_types_supported": [
"authorization_code",
"implicit",
"refresh_token",
"urn:ietf:params:oauth:grant-type:jwt-bearer"
],
"response_modes_supported": ["query", "fragment", "form_post"],
"acr_values_supported": [
"urn:mace:incommon:iap:silver",
"urn:mace:incommon:iap:bronze"
],
"id_token_encryption_alg_values_supported": ["RSA-OAEP", "RSA1_5"],
"id_token_encryption_enc_values_supported": ["A128GCM", "A256GCM"],
"request_object_signing_alg_values_supported": ["RS256", "ES256"],
"display_values_supported": ["page", "popup", "touch", "wap"],
"claim_types_supported": ["normal", "distributed", "aggregated"],
"claims_locales_supported": ["en-US", "fr-FR", "es-ES"],
"ui_locales_supported": ["en-US", "fr-FR"],
"service_documentation": "https://provider.example.com/docs",
"op_policy_uri": "https://provider.example.com/policy",
"op_tos_uri": "https://provider.example.com/tos",
}
Using the Config for Security Checks
def validate_config_for_client(config, client_config):
errors = []
# Check response type support
if client_config["response_type"] not in config.get("response_types_supported", []):
errors.append(f"Response type {client_config['response_type']} not supported")
# Check signing algorithm
if client_config.get("id_token_algorithm") not in config.get("id_token_signing_alg_values_supported", []):
errors.append(f"Algorithm {client_config['id_token_algorithm']} not supported")
# Check scopes
requested_scopes = set(client_config["scope"].split())
supported_scopes = set(config.get("scopes_supported", []))
unsupported = requested_scopes - supported_scopes
if unsupported:
errors.append(f"Unsupported scopes: {unsupported}")
return errors
Provider Extensions
Providers add custom fields to the discovery document:
# Google extensions
google_config_extras = {
"claims_parameter_supported": True,
"request_parameter_supported": True,
"request_uri_parameter_supported": True,
}
# Microsoft extensions
microsoft_config_extras = {
"cloud_instance_name": "microsoftonline.com",
"tenant_region_scope": "NA",
"cloud_graph_host_name": "graph.windows.net",
"msgraph_host": "graph.microsoft.com",
}
Common Mistakes
1. Assuming All Fields Are Present
Many providers omit optional fields. Always check with .get() and provide defaults.
2. Ignoring subject_types_supported
pairwise subject type means the sub claim differs per client. If your app expects the same sub across clients, verify support for public.
3. Not Checking response_modes_supported
If your app uses form_post mode but the provider only supports query, the auth response will not be delivered correctly.
4. Skipping Timeout on Discovery Fetch
A hanging discovery request blocks authentication for all users. Always set a timeout (e.g., 5 seconds).
5. Using Env-Specific URLs Without Checks
A provider's discovery URL for production differs from staging. Validate the issuer matches the expected environment.
Practice Questions
- What are the four REQUIRED fields in the discovery document?
- Why should you check
response_types_supportedbefore sending an auth request? - What is the difference between
publicandpairwisesubject types? - How does
grant_types_supportedaffect your token exchange Strategy? - Why might a provider add custom fields to the discovery document?
Answers:
issuer,authorization_endpoint,token_endpoint,jwks_uri, andresponse_types_supported.- If your
response_typeis not supported, the provider returns an error instead of an auth code or token. publicmeans thesubclaim is the same across all clients.pairwisemeans each client gets a differentsubfor privacy.- If the provider does not support
refresh_token, you cannot obtain refresh tokens for long-lived sessions. - Custom fields advertise additional features (e.g.,
claims_parameter_supported,request_parameter_supported) that providers offer beyond the standard.
Challenge: Write a validation script that checks whether a provider's discovery document supports all the features your OIDC client needs. Include checks for response types, signing algorithms, scopes, and grant types.
FAQ
Mini Project
Build a Python CLI tool that takes an issuer URL, fetches the well-known configuration, and prints a formatted report of all standard fields, provider extensions, and any missing required fields. Include validation warnings for unsupported features.
What's Next
Continue with OIDC Scopes to control which claims you receive, or explore Authentication Request for building OIDC authorization URLs.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro