You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js验证Azure OAuth JWT令牌遇密钥错误,求排查

解决Azure JWT令牌验证时的JsonWebTokenError: secret or public key must be provided错误

你的代码存在几个关键问题导致了这个错误,以下是修复方案和问题分析:

问题分析

  1. 未处理密钥获取失败的情况:当_client.getSigningKey调用出错,或者返回的key中没有publicKey/rsaPublicKey时,signingKey会是undefined,此时直接调用callback(null, signingKey)会导致jwt.verify无法拿到有效密钥,触发错误。
  2. 重复创建JWKS客户端实例:每次调用getSigningKeys都新建一个jwksClient实例,既影响性能,也可能引发不必要的网络请求问题。
  3. 缺少错误传递逻辑:获取密钥过程中出现的错误没有传递给jwt.verify的回调,导致验证流程无法感知到密钥获取失败。

修复后的代码

import jwt, { Algorithm, GetPublicKeyOrSecret } from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
import { promisify } from 'util';

// 提前创建JWKS客户端实例,避免重复初始化
const client = jwksClient({
  jwksUri: `https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys`,
});

const getSigningKeys: GetPublicKeyOrSecret = (header, callback) => {
  client.getSigningKey(header.kid, (err, key) => {
    if (err) {
      // 传递密钥获取错误给验证流程
      return callback(err);
    }
    const signingKey = key?.publicKey || key?.rsaPublicKey;
    if (!signingKey) {
      // 当无法提取有效公钥时,返回明确错误
      return callback(new Error('Failed to extract valid public key from JWKS'));
    }
    callback(null, signingKey);
  });
};

export const verifyMicrosoftToken = async (tokenId: string): Promise<any> => {
  const validationOptions = {
    audience: CLIENT_ID,
    issuer: `https://login.microsoftonline.com/${TENANT_ID}/v2.0`, // 标准字段为issuer,jsonwebtoken也兼容iss,但建议用标准字段名
    algorithms: ['RS256'] as Algorithm[],
  };

  try {
    const decodedToken = await promisify(jwt.verify)(
      tokenId,
      getSigningKeys,
      validationOptions
    );
    return decodedToken;
  } catch (err) {
    // 可在此统一处理验证错误,比如日志记录
    throw err;
  }
};

额外检查项

  • 确认TENANT_ID和CLIENT_ID常量/环境变量已正确配置,值与Azure AD应用注册中的信息完全一致。
  • 验证JWT令牌为Azure AD v2.0版本,可通过解码令牌前几位查看iss字段是否与代码中的issuer值匹配。
  • 检查网络是否能正常访问Azure的JWKS端点,避免防火墙或代理阻止请求。

内容的提问来源于stack exchange,提问作者Roberto Rossini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 04:16:11