Teams自定义应用以应用身份调用Microsoft Graph API问题咨询
问题说明
- 开发需求:基于TeamsFx SDK开发Teams自定义应用,需使用无用户上下文的应用身份调用Microsoft Graph API,参考官方文档对应"Create MicrosoftGraphClient service"下的"Invoke Graph API without user (Application Identity)"章节操作后未实现预期效果。
- 触发报错:控制台输出错误 Application identity is not supported in TeamsFx
- 复现操作:
- 在VS Code中使用Teams Toolkit,基于"SSO-enabled tab"示例创建全新Teams应用
- 编辑前端Graph.jsx文件,直接在前端React逻辑中初始化App身份的Graph客户端调用用户查询接口,代码如下:
import { createMicrosoftGraphClient, IdentityType, TeamsFx } from "@microsoft/teamsfx"; useEffect(() => { const getProfile = async () => { const teamsfx = new TeamsFx(IdentityType.App); const graphClient = createMicrosoftGraphClient(teamsfx); const profile = await graphClient.api("/users/username@domain.onmicrosoft.com").get(); return profile; }; const profile = getProfile(); }, []);- 按F5启动本地调试,触发上述报错。
错误根因
应用身份调用Graph需要使用AAD应用的客户端密钥、证书等敏感凭证,这类凭证绝对不能暴露在公开可访问的前端浏览器代码中,因此TeamsFx SDK的前端浏览器版本直接禁用了IdentityType.App身份模式,文档中描述的应用身份调用逻辑仅适用于Node.js后端运行环境,直接把对应代码抄到前端Tab页面中必然触发该报错。
修正方案
1. 配置AAD应用权限
- 在Teams Toolkit的AAD应用配置页,添加调用Graph所需的应用类型权限(注意不是委托权限,例如查询指定用户信息需要添加
User.Read.All应用权限) - 完成权限配置后,执行管理员同意流程,给对应应用授予租户级的应用权限。
2. 将应用身份调用逻辑迁移到后端服务
禁止在前端代码中初始化App身份的Graph客户端,所有应用身份的Graph调用全部放到后端实现:
- 如果使用Teams Toolkit默认生成的Azure Functions作为后端,直接在Function代码中编写Graph调用逻辑,SDK会自动从后端环境变量读取AAD应用的配置信息,不需要手动硬编码密钥,参考代码:
// 后端Node.js环境代码(不要放在前端src目录下) const { app } = require("@azure/functions"); const { createMicrosoftGraphClient, IdentityType, TeamsFx } = require("@microsoft/teamsfx"); app.http("getUserProfile", { methods: ["GET"], authLevel: "anonymous", handler: async (request, context) => { try { // 后端环境可安全加载敏感凭证,不会泄露给前端用户 const teamsfx = new TeamsFx(IdentityType.App); // 指定Graph默认权限范围 const graphClient = createMicrosoftGraphClient(teamsfx, ["https://graph.microsoft.com/.default"]); // 调用应用身份接口查询指定用户 const profile = await graphClient.api("/users/username@domain.onmicrosoft.com").get(); return { jsonBody: profile }; } catch (err) { context.error(err); return { status: 500, jsonBody: { error: err.message } }; } } });
3. 前端改为调用自有后端接口
修改前端Graph.jsx的逻辑,不再直接调用Graph,改为请求自己的后端接口获取数据:
import { useEffect, useState } from "react"; export const Graph = () => { const [profile, setProfile] = useState(null); useEffect(() => { const fetchProfile = async () => { // 请求自有后端接口,由后端完成应用身份的Graph调用 const res = await fetch("/api/getUserProfile"); const data = await res.json(); setProfile(data); }; fetchProfile(); }, []); return profile ? <div>用户名:{profile.displayName}</div> : <div>加载中...</div>; };
4. 本地调试注意事项
按F5启动调试前,确认Teams Toolkit已经自动为后端环境注入了AAD应用的TENANT_ID、CLIENT_ID、CLIENT_SECRET环境变量,不需要手动在代码中配置这类敏感参数。
内容的提问来源于stack exchange,提问作者Nakayama Naoto
相关产品推荐
相关产品推荐

