Discover and create an OpenID Connect (OIDC) OAuthProvider
Source:R/providers__oidc_discovery.R
oauth_provider_oidc_discover.RdBuilds an OAuthProvider from the provider's OpenID Connect discovery
document at /.well-known/openid-configuration. When present,
introspection_endpoint is also wired into the resulting provider.
Usage
oauth_provider_oidc_discover(
issuer,
name = NULL,
use_pkce = TRUE,
use_nonce = TRUE,
id_token_validation = TRUE,
token_auth_style = NULL,
allowed_algs = c("RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "EdDSA"),
allowed_token_types = c("Bearer"),
jwks_host_issuer_match = TRUE,
issuer_match = c("url", "host", "none"),
...
)Arguments
- issuer
The OIDC issuer base URL (including scheme), e.g., "https://login.example.com"
- name
Optional friendly provider name. Defaults to the issuer hostname
- use_pkce
Logical, whether to use PKCE for this provider. Defaults to TRUE. If the discovery document indicates
token_endpoint_auth_methods_supportedincludes "none", PKCE is required unlessuse_pkceis explicitly set to FALSE (not recommended)- use_nonce
Logical, whether to use OIDC nonce. Defaults to TRUE
- id_token_validation
Logical, whether to validate ID tokens automatically for this provider. Defaults to TRUE
- token_auth_style
Authentication style for token requests: "header" (client_secret_basic), "body" (client_secret_post), or "public" (public client; send
client_idonly). The alias"none"is also accepted for"public". If NULL (default), it is inferred conservatively from discovery. When PKCE is enabled and the provider advertises support for public clients vianone, discovery selects"public". Otherwise, the helper prefers"header"(client_secret_basic) when available, then"body"(client_secret_post). JWT-based methods are not auto-selected unless explicitly requested.- allowed_algs
Character vector of allowed ID token signing algorithms. Defaults to a broad set of common algorithms, including RSA (RS*), ECDSA (ES*), and EdDSA. If the discovery document advertises supported algorithms, the intersection of advertised and caller-provided algorithms is used to avoid runtime mismatches. If there's no overlap, discovery fails with a configuration error (no fallback).
- allowed_token_types
Character vector of allowed token types for access tokens issued by this provider. Defaults to 'Bearer'
- jwks_host_issuer_match
When TRUE (default), enforce that the JWKS host discovered from the provider matches the issuer host exactly. For providers that serve JWKS from a different host, set
jwks_host_allow_onlyto the exact hostname instead of disabling this. Disabling (FALSE) is not recommended unless you also pin JWKS viajwks_host_allow_onlyorjwks_pins.- issuer_match
Character scalar controlling how strictly to validate the discovery document's
issueragainst the inputissuer."url"(default): require the full issuer URL to match after trailing-slash normalization (recommended)."host": compare only scheme + host (explicit opt-out; not recommended)."none": do not validate issuer consistency.
Prefer
"url"and tighten hosts viaoptions(shinyOAuth.allowed_hosts)when feasible.- ...
Additional fields passed to
oauth_provider()(for example,pkce_method = "plain"when a provider explicitly advertises only plain PKCE support and you intentionally want to allow that downgrade).
Value
OAuthProvider object configured from discovery
Details
Most users can accept the defaults here. The points below are mainly reference for advanced provider setups or for understanding why discovery might fail early.
ID token algorithms: by default this helper accepts common asymmetric algorithms RSA (RS*), ECDSA (ES*), and EdDSA. When the provider advertises its supported ID token signing algorithms via
id_token_signing_alg_values_supported, the helper uses the intersection with the caller-providedallowed_algs. If there is no overlap, discovery fails with a configuration error. There is no automatic fallback to the discovery-advertised set.Token endpoint authentication methods: supports
client_secret_basic(header),client_secret_post(body), public clients usingnone(mapped totoken_auth_style = "public"when PKCE is enabled), as well as JWT-based methodsprivate_key_jwtandclient_secret_jwtper RFC 7523. Discovery also preserves RFC 8705 mTLS metadata (mtls_endpoint_aliasesandtls_client_certificate_bound_access_tokens) and supports explicittls_client_auth/self_signed_tls_client_authselection.PAR metadata: when the discovery document advertises
pushed_authorization_request_endpointorrequire_pushed_authorization_requests, the resulting provider stores that PAR capability and policy metadata so authorization requests can use RFC 9126 PAR and fail fast on PAR-only provider policies.Request Object metadata: when the discovery document advertises
request_object_signing_alg_values_supportedorrequire_signed_request_object, the resulting provider stores that metadata soOAuthClientcan fail fast when a request-object algorithm is unsupported or when the provider requires signed Request Objects.Authorization request transport metadata: when the discovery document advertises
request_parameter_supported,request_uri_parameter_supported, orrequire_request_uri_registration, the resulting provider stores that metadata so shinyOAuth can fail fast when a provider explicitly disallows the front-channelrequesttransport used by JAR or caller-managedrequest_urivalues. When PAR is configured, shinyOAuth sends signed Request Objects to the PAR endpoint and the browser redirect only carries the PAR-issuedrequest_urihandle, regardless ofrequest_uri_parameter_supported. When discovery omits these booleans, this helper applies the OpenID Connect defaults instead of storingNA.Token endpoint JWT auth metadata: when the discovery document advertises
token_endpoint_auth_signing_alg_values_supported, the resulting provider stores that metadata soOAuthClientcan fail fast when a JWT client assertion algorithm is unsupported.RFC 9207 callback issuer metadata: when the discovery document advertises
authorization_response_iss_parameter_supported = true, the resulting provider stores that metadata sooauth_client()can auto-enable callback issuer enforcement unless you explicitly opt out.PKCE method discovery: this helper keeps
S256as the default and does not silently downgrade toplain. If discovery metadata explicitly omitsS256, discovery fails with a configuration error unless you explicitly opt intopkce_method = "plain".Important: discovery metadata lists methods supported across the provider, not per-client provisioning. This helper does not automatically select JWT-based methods just because they are advertised. By default it prefers
client_secret_basic(header) when available, otherwiseclient_secret_post(body), and maps publicnonetotoken_auth_style = "public"only for PKCE clients. If a provider advertises only JWT methods, you must explicitly settoken_auth_styleand configure the corresponding credentials on your OAuthClient (a private key forprivate_key_jwt, or a sufficiently strongclient_secretforclient_secret_jwt).Host policy: by default, discovered standard endpoints must be absolute URLs whose host matches the issuer host exactly. Subdomains are NOT implicitly allowed. If you want to allow subdomains, add a leading-dot or glob in
options(shinyOAuth.allowed_hosts), e.g.,.example.comor*.example.com. If a global whitelist is supplied viaoptions(shinyOAuth.allowed_hosts), discovery will restrict endpoints to that whitelist. RFC 8705mtls_endpoint_aliasesare validated separately: they may use a different host or port by default, but an explicitshinyOAuth.allowed_hostswhitelist still constrains them. Scheme policy (https/http for loopback) is delegated tois_ok_host(), so you may allow non-HTTPS hosts withoptions(shinyOAuth.allowed_non_https_hosts)(see?is_ok_host).
Examples
# Configure generic OAuth 2.0 provider (no OIDC)
generic_provider <- oauth_provider(
name = "example",
auth_url = "https://example.com/oauth/authorize",
token_url = "https://example.com/oauth/token",
# Optional URL for fetching user info:
userinfo_url = "https://example.com/oauth/userinfo"
)
# Configure generic OIDC provider manually
# (This defaults to using nonce & ID token validation)
generic_oidc_provider <- oauth_provider_oidc(
name = "My OIDC",
base_url = "https://my-issuer.example.com"
)
# Configure a OIDC provider via OIDC discovery
# (requires network access)
if (interactive()) {
# Using Auth0 sample issuer as an example
oidc_discovery_provider <- oauth_provider_oidc_discover(
issuer = "https://samples.auth0.com"
)
}
# GitHub preconfigured provider
github_provider <- oauth_provider_github()
# Google preconfigured provider
google_provider <- oauth_provider_google()
# Microsoft preconfigured provider
# See `?oauth_provider_microsoft` for example using a custom tenant ID
# Spotify preconfigured provider
spotify_provider <- oauth_provider_spotify()
# Slack via OIDC discovery
# (requires network access)
if (interactive()) {
slack_provider <- oauth_provider_slack()
}
# Keycloak
# (requires configured Keycloak realm; example below is therefore not run)
if (interactive()) {
oauth_provider_keycloak(base_url = "http://localhost:8080", realm = "myrealm")
}
# Auth0
# (requires configured Auth0 domain; example below is therefore not run)
if (interactive()) {
oauth_provider_auth0(domain = "your-tenant.auth0.com")
}
# Okta
# (requires configured Okta domain; example below is therefore not run)
if (interactive()) {
oauth_provider_okta(domain = "dev-123456.okta.com")
}