Skip to content

CoreClient should respect token_endpoint_auth_methods_supported from provider metadata #215

@smihica

Description

@smihica

version: 4.0.1

Summary

The CoreClient::from_provider_metadata constructor does not seem to respect the token_endpoint_auth_methods_supported field from the discovered ProviderMetadata. The client defaults to using ClientSecretBasic authentication, even when the provider (like Apple) explicitly states it only supports ClientSecretPost, causing token exchange requests to fail with an invalid_client error.

Steps to Reproduce

  1. Use a provider that only supports client_secret_post. Apple is a perfect example: https://appleid.apple.com/.well-known/openid-configuration
  2. Discover the provider metadata: ProviderMetadata::discover_async(...).
  3. Instantiate a client using the metadata: CoreClient::from_provider_metadata(metadata, ...).
  4. Attempt a token exchange: client.exchange_code(...).

Expected Behavior

The CoreClient should inspect the token_endpoint_auth_methods_supported from the provided metadata. If ClientSecretBasic is not supported but ClientSecretPost is, it should automatically configure itself to use ClientSecretPost for the token request. The exchange_code call should succeed.

Actual Behavior

The CoreClient ignores the metadata's supported methods and defaults to ClientSecretBasic. This sends an Authorization: Basic ... header, which the provider rejects, causing the exchange_code call to fail.

Workaround

The current workaround is to manually inspect the metadata and configure the client's authentication method after instantiation. This works correctly but feels like something the library could handle automatically.

// Discover metadata as usual
let provider_metadata = CoreProviderMetadata::discover_async(issuer_url, http_client).await?;

let mut client = CoreClient::from_provider_metadata(provider_metadata.clone(), client_id, client_secret: Some(client_secret));

// Manually set the auth method if the provider doesn't support the default
if !provider_metadata
    .token_endpoint_auth_methods_supported()
    .map_or(false, |methods| {
        methods.contains(&CoreClientAuthMethod::ClientSecretBasic)
    })
{
    // Set the auth method to `client_secret_post`
    client = client.set_auth_type(openidconnect::AuthType::RequestBody);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions