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

如何合并Microsoft Azure双API请求?解决数据与头像加载冲突

解决Azure AD登录中数据库访问与头像获取的权限冲突

问题本质

你遇到的核心问题是Azure AD令牌的受众(aud声明)限制:

  • 使用${clientId}/.default时,令牌的受众是你的应用Client ID,仅拥有访问用户专属数据库的权限,无Microsoft Graph访问权限,因此无法获取用户头像;
  • 使用https://graph.microsoft.com/.default时,令牌的受众是Graph API,仅能调用Graph接口获取头像,但无访问你的数据库的权限,导致应用加载失败。

单个Azure AD令牌只能对应一个目标资源(受众),因此不能用同一个令牌同时访问你的应用数据库和Graph API,必须分开处理。

方案一:获取双令牌(推荐)

通过一次授权申请所有必要权限,再利用刷新令牌分别获取针对应用数据库和Graph API的独立令牌。

代码修改步骤

  1. 更新授权请求的权限范围
    同时申请应用默认权限和Graph的User.Read权限:
// 合并应用权限与Graph权限
const scope = `${clientId}/.default https://graph.microsoft.com/User.Read offline_access`;
  1. 保留原令牌请求逻辑(获取数据库访问令牌)
    维持tokenRequestScope为${clientId}/.default,该令牌用于访问用户专属数据库:
const tokenRequestScope = `${clientId}/.default`;
  1. 新增Graph令牌获取函数
    利用已获取的刷新令牌,请求针对Graph API的专用令牌:
async function requestGraphToken() {
    const refreshToken = localStorage.getItem('refresh_token');
    if (!refreshToken) return null;

    const tokensRequestUrl = `${baseUrl}/token?`;
    const config = {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        }
    };
    const body = {
        'client_id': clientId,
        'scope': 'https://graph.microsoft.com/User.Read',
        'refresh_token': refreshToken,
        'grant_type': 'refresh_token',
    };

    try {
        const response = await axios.post(tokensRequestUrl, body, config);
        if (response.status === 200) {
            localStorage.setItem('graph_access_token', response.data.access_token);
            return response.data.access_token;
        }
    } catch (err) {
        console.error('Failed to get Graph token:', err);
        return null;
    }
}
  1. 登录成功后自动获取Graph令牌
    修改check_auth_code函数,在登录完成后触发Graph令牌请求:
async function check_auth_code(authCode, onSuccess, onError) {
    if (authCode) {
        try {
            const data = await requestTokens(authCode);
            if (data) {
                localStorage.setItem('access_token', data.access_token);
                localStorage.setItem('refresh_token', data.refresh_token);
                // 获取Graph专用令牌
                await requestGraphToken();
                console.log('Success login');
                onSuccess();
            } else {
                console.log('Error login');
                onError();
            }
        } catch (err) {
            console.error('Login error:', err);
            onError();
        }
    }
}
  1. 分场景使用令牌
  • 访问用户数据库时,使用存储的access_token;
  • 调用Graph API获取头像时,使用graph_access_token。

方案二:增量授权(可选)

如果不想一次性申请所有权限,可以先完成数据库访问的登录流程,当需要获取头像时,触发增量授权请求Graph权限:

function requestGraphAuthCode() {
    const authCodeRequestUrl = `${baseUrl}/authorize?` +
        `client_id=${clientId}` +
        `&response_type=code` +
        `&redirect_uri=${redirectUri}` +
        `&response_mode=query` +
        `&scope=https://graph.microsoft.com/User.Read` +
        `&prompt=consent`; // 强制用户确认新权限
    window.open(authCodeRequestUrl, "_self");
}

在回调页面中,用新的授权码获取Graph令牌,并存入独立存储位置。

必要配置检查

确保你的Azure AD应用已完成以下配置:

  • 添加了针对用户数据库的自定义API权限或应用角色,并完成管理员同意;
  • 添加了Microsoft Graph的User.Read委派权限,并完成管理员同意;
  • 应用的重定向URI配置正确,包含开发和生产环境的地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 07:44:54