From 15f97ff0ff043d1379b99fa8adf0519bc73abb60 Mon Sep 17 00:00:00 2001 From: Ted Date: Thu, 20 Feb 2025 20:21:16 +0000 Subject: [PATCH] feat(oidc): allow header auth for token endpoint (#1484) --- .../src/plugins/oidc-provider/index.ts | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/better-auth/src/plugins/oidc-provider/index.ts b/packages/better-auth/src/plugins/oidc-provider/index.ts index 8abcfa1621..a269c9653d 100644 --- a/packages/better-auth/src/plugins/oidc-provider/index.ts +++ b/packages/better-auth/src/plugins/oidc-provider/index.ts @@ -21,6 +21,7 @@ import type { import { authorize } from "./authorize"; import { parseSetCookieHeader } from "../../cookies"; import { createHash } from "@better-auth/utils/hash"; +import { base64 } from "@better-auth/utils/base64"; const getMetadata = ( ctx: GenericEndpointContext, @@ -268,9 +269,41 @@ export const oidcProvider = (options: OIDCOptions) => { error: "invalid_request", }); } + let { client_id, client_secret } = body; + const authorization = + ctx.request?.headers.get("authorization") || null; + if ( + authorization && + !client_id && + !client_secret && + authorization.startsWith("Basic ") + ) { + try { + const encoded = authorization.replace("Basic ", ""); + const decoded = new TextDecoder().decode(base64.decode(encoded)); + if (!decoded.includes(":")) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid authorization header format", + error: "invalid_client", + }); + } + const [id, secret] = decoded.split(":"); + if (!id || !secret) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid authorization header format", + error: "invalid_client", + }); + } + client_id = id; + client_secret = secret; + } catch (error) { + throw new APIError("UNAUTHORIZED", { + error_description: "invalid authorization header format", + error: "invalid_client", + }); + } + } const { - client_id, - client_secret, grant_type, code, redirect_uri,