"client_secret_basic" — credentials in HTTP Basic Authorization header.
"client_secret_post" — credentials in form-encoded body parameters.
"none" — public client; only client_id (in body) is
supplied. PKCE/S256 is mandated separately at /authorize (see routes.mts).
Enforcement (D-6 PB-2):
The configured tokenEndpointAuthMethod on the client record selects the
accepted transport. Wrong-transport attempts (e.g. client_secret_post
body sent to a client_secret_basic client) reject with invalid_client
400/401, matching RFC 6749 §5.2.
If both Basic and body credentials are present and the client_id (or
client_secret) values disagree, reject with invalid_client 401 —
prevents credential-confusion attacks where an attacker pins a victim's
Basic header and supplies their own body credentials, or vice versa.
WWW-Authenticate: Basic realm="<issuer>" is emitted in two cases:
(a) the failed attempt was Basic (RFC 7235 §2.1 challenge advertisement),
and (b) no credentials were supplied at all (so the caller is told that
Basic is an accepted retry transport). It is NOT emitted on
client_secret_post failures or public-client rejections — those callers
should not be redirected to Basic. The <issuer> realm value is
validated against a safe character set; misconfigured issuers fall back
to the literal oauth realm.
On success: sets req.oauthClient to the authenticated PublicClient
and calls next().
On failure: responds with 400/401, JSON body
{ error: "invalid_client", error_description?: string }, and (when
applicable) WWW-Authenticate. The repository-throw path intentionally omits
error_description so that internal store details do not leak to callers.
Creates RFC 6749 §2.3.1 client-authentication middleware suitable for both
/oauth/introspectand/oauth/token.Authentication discriminator (RFC 6749 §2.3 / RFC 7591 §2):
"client_secret_basic"— credentials in HTTP BasicAuthorizationheader."client_secret_post"— credentials in form-encoded body parameters."none"— public client; onlyclient_id(in body) is supplied. PKCE/S256 is mandated separately at/authorize(seeroutes.mts).Enforcement (D-6 PB-2):
tokenEndpointAuthMethodon the client record selects the accepted transport. Wrong-transport attempts (e.g.client_secret_postbody sent to aclient_secret_basicclient) reject withinvalid_client400/401, matching RFC 6749 §5.2.client_id(orclient_secret) values disagree, reject withinvalid_client401 — prevents credential-confusion attacks where an attacker pins a victim's Basic header and supplies their own body credentials, or vice versa.WWW-Authenticate: Basic realm="<issuer>"is emitted in two cases: (a) the failed attempt was Basic (RFC 7235 §2.1 challenge advertisement), and (b) no credentials were supplied at all (so the caller is told that Basic is an accepted retry transport). It is NOT emitted onclient_secret_postfailures or public-client rejections — those callers should not be redirected to Basic. The<issuer>realm value is validated against a safe character set; misconfigured issuers fall back to the literaloauthrealm.On success: sets
req.oauthClientto the authenticated PublicClient and callsnext().On failure: responds with 400/401, JSON body
{ error: "invalid_client", error_description?: string }, and (when applicable)WWW-Authenticate. The repository-throw path intentionally omitserror_descriptionso that internal store details do not leak to callers.