使用应用权限调用Microsoft Graph Presence端点返回403错误求助
解决Microsoft Graph API获取Teams Presence返回403 Forbidden的问题
核心问题排查与修复步骤
确认权限的管理员同意状态
你提到已开启Presence的应用权限,但仅在Azure门户添加权限还不够——Presence.Read.All/Presence.ReadWrite.All这类应用权限必须由全局管理员或Teams管理员授予「管理员同意」。- 进入Azure AD应用的「API权限」页面,找到已添加的Presence权限,确认状态是「已同意」而非「需要管理员同意」。如果是后者,点击「授予管理员同意」按钮完成授权。
修正代码中的用户ID占位符
你的代码中var presence = await graphClient.Users["{user id}"].Presence.Request().GetAsync();使用了占位符{user id},需要替换为前面获取到的实际用户ID:// 替换为实际获取到的用户ID var presence = await graphClient.Users[userid.Id].Presence.Request().GetAsync();若未替换会导致请求无效用户ID,但403错误大概率源于权限问题,不过仍需修正该代码细节。
验证访问令牌的权限范围
生成的访问令牌必须包含Presence.Read.All权限。可将获取到的token复制到jwt.ms解析,检查scp或roles字段中是否存在该权限。如果没有,说明权限未正确授予,需重新检查Azure AD的权限配置和管理员同意步骤。
修正后的完整代码示例
static async Task MainAsync() { var tenantId = "你的租户ID"; var clientId = "你的客户端ID"; var clientSecret = "你的客户端密钥"; try { string[] scopes = { "https://graph.microsoft.com/.default" }; ClientSecretCredential clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret); GraphServiceClient graphClient = new GraphServiceClient(clientSecretCredential, scopes); // 获取目标用户的ID var targetUser = await graphClient.Users["my.name@company.com"].Request().GetAsync(); Console.WriteLine($"目标用户ID: {targetUser.Id}"); // 获取用户Presence状态 var presence = await graphClient.Users[targetUser.Id].Presence.Request().GetAsync(); Console.WriteLine($"用户状态: {presence.Availability}, {presence.Activity}"); } catch (Exception ex) { Console.WriteLine($"错误信息: {ex.Message}"); // 可添加详细错误输出,便于排查 if (ex is ServiceException serviceEx) { Console.WriteLine($"响应内容: {serviceEx.ResponseContent}"); } } }
额外说明
- Presence权限确实比User相关权限更严格,因为涉及用户实时状态隐私,微软对这类权限的授权和使用有更严格的限制。
- 该功能并非只能在Teams内使用,通过Microsoft Graph API可以在任何后端服务中调用,只要满足权限和配置要求。
- 若使用委派权限(比如你测试的设备码流项目),需要的是
Presence.Read或Presence.ReadWrite委派权限,且登录用户需有相应访问权限,同时要确保管理员同意了委派权限。
内容的提问来源于stack exchange,提问作者j.hull
相关产品推荐
相关产品推荐

