Discover and create an OpenID Connect (OIDC) OAuthProvider
Source:R/providers__oidc_discovery.R
oauth_provider_oidc_discover.RdSupply your provider's issuer URL to create an OAuthProvider without
entering each service URL yourself. The helper downloads the provider's
discovery document (OpenID Connect Discovery) and enables OIDC login checks.
Pass the result to oauth_client().
Usage
oauth_provider_oidc_discover(
issuer,
name = NULL,
use_pkce = TRUE,
use_nonce = TRUE,
id_token_validation = TRUE,
token_auth_style = NULL,
id_token_allowed_algs = c("RS256", "RS384", "RS512", "ES256", "ES384", "ES512",
"Ed25519", "EdDSA"),
allowed_token_types = c("Bearer"),
jwks_host_issuer_match = TRUE,
issuer_match = c("url", "host", "none"),
...,
allowed_algs = NULL
)Arguments
- issuer
The OIDC issuer base URL (including scheme), e.g., "https://login.example.com". The standard discovery-document URL ending in
/.well-known/openid-configurationis also accepted. Its discovered issuer must map back to that metadata location; the exact returned issuer, including any trailing slash, is retained for subsequent validation.- name
Optional friendly provider name. Defaults to the issuer hostname
- use_pkce
Logical, whether to use PKCE for this provider. Defaults to TRUE. Public clients require PKCE. Setting FALSE also prevents automatic selection of public-client authentication; a confidential-client method must be available or explicitly configured instead.
- 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:"header"(client_secret_basic) is preferred, followed by"body"(client_secret_post), then"public"ifnoneis advertised and PKCE is enabled. Settoken_auth_style = "public"explicitly for a public client registration. JWT methods ("client_secret_jwt","private_key_jwt") and mTLS methods ("tls_client_auth","self_signed_tls_client_auth") must be selected explicitly. Seeoauth_provider()for the supported methods and their credentials.- id_token_allowed_algs
Character vector of allowed ID token signing algorithms. Defaults to a broad set of common algorithms, including RSA (RS*), ECDSA (ES*), Ed25519, and legacy 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), require the discovered JWKS host to match the issuer host exactly.
jwks_host_allow_onlytakes precedence and can specify a different exact hostname.FALSEdisables issuer-host matching.- issuer_match
Character scalar controlling how strictly to validate the discovery document's
issueragainst the inputissuer."url"(default): require the issuer used for discovery to match exactly, including any trailing slash. For a full discovery URL input, require the discovered issuer's standard metadata location to match that URL."host": compare only scheme + host."none": skip issuer-consistency validation.
- ...
Additional fields passed to
oauth_provider(), includingpkce_method = "plain"for compatibility with plain-only PKCE metadata.- allowed_algs
Compatibility alias for
id_token_allowed_algs. Supply only one spelling.
Value
OAuthProvider object configured from discovery
Details
This function makes a network request. Call it once during app setup, outside
server(). Copy the issuer URL exactly from your provider's configuration,
including any trailing slash. A full discovery-document URL is also accepted.
Discovered token, UserInfo, introspection, and revocation endpoints are
copied into the provider when present. Discovering an introspection endpoint
does not itself require token introspection; set introspect = TRUE on
oauth_client() when login and refresh must perform that check.
Discovery describes the service, not your app registration. Use the client ID
and secret or key issued for your app. If the registration is public (no
secret), explicitly select token_auth_style = "public". Other authentication
choices and metadata restrictions are described below.
Advanced authentication selection
Automatic selection prefers "header", then "body", then "public" when
none is advertised and PKCE is enabled. JWT and mTLS methods require an
explicit choice. Selected methods must match the advertised metadata.
If token_endpoint_auth_methods_supported is absent, only the OIDC default
client_secret_basic ("header") is assumed.
Discovery validation
The discovered issuer must match the requested identifier by default.
Endpoints must use HTTPS. Host allowlisting does not permit HTTP: local OIDC
development requires options(shinyOAuth.allow_insecure_oidc_loopback = TRUE)
and a loopback host. options(shinyOAuth.allowed_hosts) can further restrict
endpoint hosts. Signing-key hosts have their own policy: by default they must
match the issuer host; use jwks_host_allow_only for a known different host.
The document must advertise the code flow (response_types_supported
includes "code"), non-empty subject_types_supported, RS256 in
id_token_signing_alg_values_supported, and a jwks_uri even when automatic
ID token validation is disabled. The permitted ID token algorithms are the
intersection of id_token_allowed_algs and the advertised algorithms; an empty
intersection is an error. Discovery keeps PKCE S256 and errors when the
provider explicitly excludes it, unless you select pkce_method = "plain".
Advanced metadata
Discovery also records capabilities for PAR, signed/encrypted requests,
JARM, DPoP, mTLS, and callback issuer identification. Client construction
checks the selected features against this metadata. See oauth_provider()
for individual fields and the advanced security vignette for setup.
When omitted by the provider, OIDC defaults apply: the JAR request
parameter is unsupported, request URIs are supported, request URI registration is not
required, and response modes are c("query", "fragment"). A mode still
has to be implemented by shinyOAuth to be usable. Caller-published request
URI registration must be arranged with the provider; discovery cannot check
your registration. PAR-issued handles do not need that client-hosted URI
registration.
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"
)
# Look up an OIDC provider's settings with 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
# For a complete app using a custom tenant ID, see:
# https://lukakoning.github.io/shinyOAuth/reference/oauth_provider_microsoft.html
# 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()) {
options(shinyOAuth.allow_insecure_oidc_loopback = TRUE)
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")
}