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

Azure Function调用Graph API时遇“Access Token缺失或格式错误”问题

Azure Function调用Azure AD Graph API时出现“Access Token缺失或格式错误”问题排查

问题描述

我正在开发一个与Azure Active Directory Graph API(@azure/graph)交互的Azure Function,用于验证邮箱是否在Azure AD(Entra ID)中已注册并验证。调用graphClient.users.list方法通过邮箱获取用户信息时,抛出以下错误:

使用Postman测试API http://localhost:7071/api/checkEmail时的错误:
Error verifying email: RestError: {"odata.error":{"code":"Authentication_MissingOrMalformed","codeForMetrics":"Authentication_MissingOrMalformed","message":{"lang":"en","value":"Access Token missing or malformed."}}}

已确认环境变量(AZURE_TENANT_ID、AZURE_CLIENT_ID、AZURE_CLIENT_SECRET)配置正确,尝试过DefaultAzureCredential和ClientSecretCredential,问题依旧,应用注册的Azure AD权限配置无异常。

相关代码如下:

const { GraphRbacManagementClient } = require("@azure/graph");
const { DefaultAzureCredential } = require("@azure/identity");

const tenantId = process.env.AZURE_TENANT_ID;

module.exports = async function (context, req) {
    context.log('Checking if email is verified...');

    const { email } = req.body;

    if (!email) {
        context.res = {
            status: 400,
            body: "Please provide the email"
        };
        return;
    }

    try {
        const credential = new DefaultAzureCredential();
        const graphClient = new GraphRbacManagementClient(
            credential,
            tenantId
        );

        const verifyEmail = async (email) => {
            try {
                const users = await graphClient.users.list({ filter: `mail eq '${email}'` });
                const user = users.next().value;

                if (user) {
                    if (user.mailVerified) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            } catch (error) {
                console.error("Error verifying email:", error);
                return false;
            }
        };
        const isEmailVerified = await verifyEmail(email);

        if (isEmailVerified) {
            context.res = {
                status: 200,
                body: "Email is verified"
            };
        } else {
            context.res = {
                status: 400,
                body: "Email is not verified or does not exist"
            };
        }
    } catch (error) {
        console.error("Error:", error);
        context.res = {
            status: 500,
            body: "Internal Server Error"
        };
    }
};

问题原因及解决方案

核心原因

@azure/graph(Azure AD Graph API)要求的令牌受众(audience)为https://graph.windows.net,但DefaultAzureCredential默认会请求Microsoft Graph API的令牌(受众为https://graph.microsoft.com),两者受众不匹配,导致Azure AD Graph API判定令牌格式错误或缺失。

解决方案

需要明确指定令牌的作用域为Azure AD Graph API的要求,具体有两种实现方式:

方法1:创建Graph客户端时指定作用域

修改GraphRbacManagementClient的初始化代码,添加scopes参数:

const graphClient = new GraphRbacManagementClient(
    credential,
    tenantId,
    {
        scopes: ["https://graph.windows.net/.default"]
    }
);

方法2:使用ClientSecretCredential时直接指定作用域

如果使用ClientSecretCredential替代DefaultAzureCredential,可在初始化凭据时指定作用域:

const { ClientSecretCredential } = require("@azure/identity");

// 替换原DefaultAzureCredential初始化代码
const credential = new ClientSecretCredential(
    tenantId,
    process.env.AZURE_CLIENT_ID,
    process.env.AZURE_CLIENT_SECRET,
    {
        scopes: ["https://graph.windows.net/.default"]
    }
);
const graphClient = new GraphRbacManagementClient(credential, tenantId);

额外检查点

  • 确认应用注册已添加Azure AD Graph API的应用权限(而非Microsoft Graph),并完成管理员同意,常用权限为User.Read.All。
  • 本地调试时,可通过console.log(process.env.AZURE_CLIENT_ID)验证环境变量是否正确加载。
  • Azure Function作为后台服务,应使用应用权限而非用户委托权限,避免权限范围不匹配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:26:28