mics: support no KID in header during OIDC login

This commit is contained in:
Sheen Capadngan
2025-11-11 22:24:41 +08:00
parent 6e622c8f8c
commit c35cebd26b
@@ -111,34 +111,88 @@ export const identityOidcAuthServiceFactory = ({
requestAgent: identityOidcAuth.oidcDiscoveryUrl.includes("https") ? requestAgent : undefined requestAgent: identityOidcAuth.oidcDiscoveryUrl.includes("https") ? requestAgent : undefined
}); });
const { kid } = decodedToken.header as { kid: string }; const { kid } = decodedToken.header as { kid?: string };
let oidcSigningKey; let tokenData: Record<string, string> | undefined;
try {
oidcSigningKey = await client.getSigningKey(kid); // If kid is provided, try to get the specific signing key
} catch (error) { if (kid) {
if (error instanceof Error && error.name === "SigningKeyNotFoundError") { let oidcSigningKey;
try {
oidcSigningKey = await client.getSigningKey(kid);
} catch (error) {
if (error instanceof Error && error.name === "SigningKeyNotFoundError") {
throw new UnauthorizedError({
message: `Access denied: Unable to verify JWT signature. The signing key '${kid}' was not found in the OIDC provider's JWKS endpoint. This may indicate an invalid token or misconfigured OIDC provider.`
});
}
throw new UnauthorizedError({ throw new UnauthorizedError({
message: `Access denied: Unable to verify JWT signature. The signing key '${kid}' was not found in the OIDC provider's JWKS endpoint. This may indicate an invalid token or misconfigured OIDC provider.` message: `Access denied: Failed to retrieve signing key from OIDC provider: ${error instanceof Error ? error.message : String(error)}`
});
}
try {
tokenData = crypto.jwt().verify(oidcJwt, oidcSigningKey.getPublicKey(), {
issuer: identityOidcAuth.boundIssuer
}) as Record<string, string>;
} catch (error) {
if (error instanceof jwt.JsonWebTokenError) {
throw new UnauthorizedError({
message: `Access denied: ${error.message}`
});
}
throw error;
}
} else {
// If kid is not provided, try all available signing keys
let allSigningKeys;
try {
allSigningKeys = await client.getSigningKeys();
} catch (error) {
throw new UnauthorizedError({
message: `Access denied: Failed to retrieve signing keys from OIDC provider: ${error instanceof Error ? error.message : String(error)}`
});
}
if (!allSigningKeys || allSigningKeys.length === 0) {
throw new UnauthorizedError({
message: "Access denied: No signing keys available from OIDC provider's JWKS endpoint."
});
}
let lastError: Error | null = null;
let verified = false;
// Try each signing key until one works
for (const signingKey of allSigningKeys) {
try {
tokenData = crypto.jwt().verify(oidcJwt, signingKey.getPublicKey(), {
issuer: identityOidcAuth.boundIssuer
}) as Record<string, string>;
verified = true;
break;
} catch (error) {
if (error instanceof jwt.JsonWebTokenError) {
lastError = error;
// Continue trying other keys
} else {
throw error;
}
}
}
if (!verified) {
throw new UnauthorizedError({
message: `Access denied: Unable to verify JWT signature with any available signing key. ${lastError ? lastError.message : "Invalid token"}`
}); });
} }
throw new UnauthorizedError({
message: `Access denied: Failed to retrieve signing key from OIDC provider: ${error instanceof Error ? error.message : String(error)}`
});
} }
let tokenData: Record<string, string>; // Ensure tokenData was successfully assigned
try { if (!tokenData) {
tokenData = crypto.jwt().verify(oidcJwt, oidcSigningKey.getPublicKey(), { throw new UnauthorizedError({
issuer: identityOidcAuth.boundIssuer message: "Access denied: Failed to verify JWT token"
}) as Record<string, string>; });
} catch (error) {
if (error instanceof jwt.JsonWebTokenError) {
throw new UnauthorizedError({
message: `Access denied: ${error.message}`
});
}
throw error;
} }
if (identityOidcAuth.boundSubject) { if (identityOidcAuth.boundSubject) {