@@ -36,7 +36,7 @@ const GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:jwt-bearer';
3636 * - `getJWTBearerIssuer(issuer)` → `{ audience, jwks | jwksUri | secret }` (or
3737 * falsy for an untrusted issuer) — the verification key material and the
3838 * expected `aud`.
39- * - `getJWTBearerUser({ issuer, subject, client, scope, jti, exp })` → the
39+ * - `getJWTBearerUser({ issuer, subject, client, scope, jti, assertionId, exp })` → the
4040 * authorized user (or falsy to deny). Replay (`jti`) can be enforced here.
4141 *
4242 * @example
@@ -162,22 +162,33 @@ class JwtBearerGrantType extends AbstractGrantType {
162162 * Resolve the verification key for the issuer (HMAC secret or asymmetric JWKS).
163163 */
164164 async getKey ( issuerData , header ) {
165+ const hasSecret = typeof issuerData . secret === 'string' && issuerData . secret . length > 0 ;
166+ const hasJwks = ! ! issuerData . jwks || ! ! issuerData . jwksUri ;
167+
168+ // No key material at all is a server-side misconfiguration of the issuer.
169+ if ( ! hasSecret && ! hasJwks ) {
170+ throw new ServerError ( 'Server error: issuer has no key material for assertion verification' ) ;
171+ }
172+
165173 if ( isHmac ( header . alg ) ) {
166- if ( typeof issuerData . secret !== 'string' || issuerData . secret . length === 0 ) {
167- throw new ServerError ( 'Server error: issuer has no secret for HMAC assertion verification' ) ;
174+ // The issuer has key material, just not for this algorithm family — that
175+ // makes the assertion unverifiable against this issuer, i.e. the client's
176+ // fault, not the server's.
177+ if ( ! hasSecret ) {
178+ throw new InvalidGrantError ( 'Invalid grant: assertion algorithm does not match the issuer key material' ) ;
168179 }
169180 return new TextEncoder ( ) . encode ( issuerData . secret ) ;
170181 }
171182
172- if ( issuerData . jwks ) {
173- return createLocalJWKSet ( issuerData . jwks ) ;
183+ if ( ! hasJwks ) {
184+ throw new InvalidGrantError ( 'Invalid grant: assertion algorithm does not match the issuer key material' ) ;
174185 }
175186
176- if ( issuerData . jwksUri ) {
177- return getRemoteJwks ( issuerData . jwksUri ) ;
187+ if ( issuerData . jwks ) {
188+ return createLocalJWKSet ( issuerData . jwks ) ;
178189 }
179190
180- throw new ServerError ( 'Server error: issuer has no keys for assertion verification' ) ;
191+ return getRemoteJwks ( issuerData . jwksUri ) ;
181192 }
182193
183194 /**
0 commit comments