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,8 +111,12 @@ 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 tokenData: Record<string, string> | undefined;
// If kid is provided, try to get the specific signing key
if (kid) {
let oidcSigningKey; let oidcSigningKey;
try { try {
oidcSigningKey = await client.getSigningKey(kid); oidcSigningKey = await client.getSigningKey(kid);
@@ -127,7 +131,6 @@ export const identityOidcAuthServiceFactory = ({
}); });
} }
let tokenData: Record<string, string>;
try { try {
tokenData = crypto.jwt().verify(oidcJwt, oidcSigningKey.getPublicKey(), { tokenData = crypto.jwt().verify(oidcJwt, oidcSigningKey.getPublicKey(), {
issuer: identityOidcAuth.boundIssuer issuer: identityOidcAuth.boundIssuer
@@ -140,6 +143,57 @@ export const identityOidcAuthServiceFactory = ({
} }
throw error; 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"}`
});
}
}
// Ensure tokenData was successfully assigned
if (!tokenData) {
throw new UnauthorizedError({
message: "Access denied: Failed to verify JWT token"
});
}
if (identityOidcAuth.boundSubject) { if (identityOidcAuth.boundSubject) {
if (!doesFieldValueMatchOidcPolicy(tokenData.sub, identityOidcAuth.boundSubject)) { if (!doesFieldValueMatchOidcPolicy(tokenData.sub, identityOidcAuth.boundSubject)) {