-
-
Notifications
You must be signed in to change notification settings - Fork 133
Description
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
- Use a provider that only supports
client_secret_post. Apple is a perfect example: https://appleid.apple.com/.well-known/openid-configuration - Discover the provider metadata:
ProviderMetadata::discover_async(...). - Instantiate a client using the metadata:
CoreClient::from_provider_metadata(metadata, ...). - 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);
}