(clientInformation: OAuthClientInformationMixed, supportedMethods: string[])
| 261 | * @returns The selected authentication method |
| 262 | */ |
| 263 | export function selectClientAuthMethod(clientInformation: OAuthClientInformationMixed, supportedMethods: string[]): ClientAuthMethod { |
| 264 | const hasClientSecret = clientInformation.client_secret !== undefined; |
| 265 | |
| 266 | // Prefer the method returned by the server during client registration, if valid. |
| 267 | // When server metadata is present we also require the method to be listed as supported; |
| 268 | // when supportedMethods is empty (metadata omitted the field) the DCR hint stands alone. |
| 269 | if ( |
| 270 | 'token_endpoint_auth_method' in clientInformation && |
| 271 | clientInformation.token_endpoint_auth_method && |
| 272 | isClientAuthMethod(clientInformation.token_endpoint_auth_method) && |
| 273 | (supportedMethods.length === 0 || supportedMethods.includes(clientInformation.token_endpoint_auth_method)) |
| 274 | ) { |
| 275 | return clientInformation.token_endpoint_auth_method; |
| 276 | } |
| 277 | |
| 278 | // If server metadata omits token_endpoint_auth_methods_supported, RFC 8414 §2 says the |
| 279 | // default is client_secret_basic. RFC 6749 §2.3.1 also requires servers to support HTTP |
| 280 | // Basic authentication for clients with a secret, making it the safest default. |
| 281 | if (supportedMethods.length === 0) { |
| 282 | return hasClientSecret ? 'client_secret_basic' : 'none'; |
| 283 | } |
| 284 | |
| 285 | // Try methods in priority order (most secure first) |
| 286 | if (hasClientSecret && supportedMethods.includes('client_secret_basic')) { |
| 287 | return 'client_secret_basic'; |
| 288 | } |
| 289 | |
| 290 | if (hasClientSecret && supportedMethods.includes('client_secret_post')) { |
| 291 | return 'client_secret_post'; |
| 292 | } |
| 293 | |
| 294 | if (supportedMethods.includes('none')) { |
| 295 | return 'none'; |
| 296 | } |
| 297 | |
| 298 | // Fallback: use what we have |
| 299 | return hasClientSecret ? 'client_secret_post' : 'none'; |
| 300 | } |
| 301 | |
| 302 | /** |
| 303 | * Applies client authentication to the request based on the specified method. |
no test coverage detected
searching dependent graphs…