Skip to contents

Builds 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_supported includes "none", PKCE is required unless use_pkce is 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_id only). 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 via none, 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_only to the exact hostname instead of disabling this. Disabling (FALSE) is not recommended unless you also pin JWKS via jwks_host_allow_only or jwks_pins.

issuer_match

Character scalar controlling how strictly to validate the discovery document's issuer against the input issuer.

  • "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 via options(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-provided allowed_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 using none (mapped to token_auth_style = "public" when PKCE is enabled), as well as JWT-based methods private_key_jwt and client_secret_jwt per RFC 7523. Discovery also preserves RFC 8705 mTLS metadata (mtls_endpoint_aliases and tls_client_certificate_bound_access_tokens) and supports explicit tls_client_auth / self_signed_tls_client_auth selection.

  • PAR metadata: when the discovery document advertises pushed_authorization_request_endpoint or require_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_supported or require_signed_request_object, the resulting provider stores that metadata so OAuthClient can 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, or require_request_uri_registration, the resulting provider stores that metadata so shinyOAuth can fail fast when a provider explicitly disallows the front-channel request transport used by JAR or caller-managed request_uri values. When PAR is configured, shinyOAuth sends signed Request Objects to the PAR endpoint and the browser redirect only carries the PAR-issued request_uri handle, regardless of request_uri_parameter_supported. When discovery omits these booleans, this helper applies the OpenID Connect defaults instead of storing NA.

  • Token endpoint JWT auth metadata: when the discovery document advertises token_endpoint_auth_signing_alg_values_supported, the resulting provider stores that metadata so OAuthClient can 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 so oauth_client() can auto-enable callback issuer enforcement unless you explicitly opt out.

  • PKCE method discovery: this helper keeps S256 as the default and does not silently downgrade to plain. If discovery metadata explicitly omits S256, discovery fails with a configuration error unless you explicitly opt into pkce_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, otherwise client_secret_post (body), and maps public none to token_auth_style = "public" only for PKCE clients. If a provider advertises only JWT methods, you must explicitly set token_auth_style and configure the corresponding credentials on your OAuthClient (a private key for private_key_jwt, or a sufficiently strong client_secret for client_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.com or *.example.com. If a global whitelist is supplied via options(shinyOAuth.allowed_hosts), discovery will restrict endpoints to that whitelist. RFC 8705 mtls_endpoint_aliases are validated separately: they may use a different host or port by default, but an explicit shinyOAuth.allowed_hosts whitelist still constrains them. Scheme policy (https/http for loopback) is delegated to is_ok_host(), so you may allow non-HTTPS hosts with options(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")
}