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

使用Graph SDK 5.17.0 C#调用Microsoft Graph获取用户在线状态遇阻

解决Teams Graph API获取用户在线状态的问题

针对你遇到的两种调用问题,分别给出针对性解决方案:

1. 客户端密钥方式(Client Secret)抛出Forbidden错误

客户端密钥属于应用权限认证方式,要成功获取用户在线状态,必须满足以下条件:

  • 已配置并获得租户管理员批准的Presence.Read.All(应用权限),委托权限对客户端凭证方式完全无效。
  • 调用端点只能使用/users/{userId}/presence,无法使用/me/presence(应用权限无当前用户上下文)。
  • 确认Azure AD应用类型为机密客户端(如Web应用/API),桌面应用不推荐使用该方式,因为无法安全存储clientSecret。

若已配置权限仍报错,需额外检查:

  • 权限是否完成管理员同意(在Azure AD应用的权限页面点击「授予管理员同意」)。
  • 调用时的scopes必须使用https://graph.microsoft.com/.default,应用权限需通过该范围获取所有已配置的权限。

2. 用户名密码方式无法获取在线状态

核心排查与修正点:

  • 权限范围不匹配:
    调用/me/presence仅需Presence.Read委托权限,但调用/users/{userId}/presence需要**Presence.Read.All(委托权限)**且已获得管理员同意。代码中需将scopes调整为包含所需权限:
    var scopes = new[] { "Presence.Read", "Presence.Read.All" };
    
  • MFA限制:
    UsernamePasswordCredential不支持启用**多因素认证(MFA)**的账号,若你的账号开启了MFA,该方式会静默失败,建议改用交互式认证方案。
  • API调用上下文校验:
    • 使用graphClient.Me.Presence.GetAsync()时,确保认证账号在Teams中有活跃状态数据。
    • 调用graphClient.Users["userid"].Presence.GetAsync()时,userid必须是用户的Object ID,若用邮箱需确保是用户的主邮箱(而非别名)。

修正后示例代码

var tenantId = "MytenantId";
var clientId = "MyclientId";

var options = new UsernamePasswordCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};

// 包含所需的所有权限范围
var scopes = new[] { "Presence.Read", "Presence.Read.All" };
var userName = "my@mail.com";
var password = "Password1!";

var userNamePasswordCredential = new UsernamePasswordCredential(
    userName, password, tenantId, clientId, options);

var graphClient = new GraphServiceClient(userNamePasswordCredential, scopes);

try
{
    // 获取当前用户状态
    var myPresence = await graphClient.Me.Presence.GetAsync();
    Console.WriteLine($"当前用户状态:{myPresence.Availability} - {myPresence.Activity}");

    // 获取指定用户状态(需Presence.Read.All权限)
    var targetUserId = "目标用户的Object ID";
    var targetPresence = await graphClient.Users[targetUserId].Presence.GetAsync();
    Console.WriteLine($"目标用户状态:{targetPresence.Availability} - {targetPresence.Activity}");
}
catch (Exception ex)
{
    Console.WriteLine($"调用失败:{ex.Message}");
    if (ex is Microsoft.Graph.ServiceException graphEx)
    {
        Console.WriteLine($"Graph错误详情:{graphEx.ResponseBody}");
    }
}

桌面应用推荐认证方案(支持MFA)

对于桌面应用,更安全且兼容MFA的方式是使用交互式浏览器认证:

var tenantId = "MytenantId";
var clientId = "MyclientId";

var options = new InteractiveBrowserCredentialOptions
{
    TenantId = tenantId,
    ClientId = clientId,
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
    // 重定向URI需提前在Azure AD应用中配置为http://localhost或自定义URI
    RedirectUri = new Uri("http://localhost"),
};

var interactiveCredential = new InteractiveBrowserCredential(options);
var scopes = new[] { "Presence.Read", "Presence.Read.All" };

var graphClient = new GraphServiceClient(interactiveCredential, scopes);

var myPresence = await graphClient.Me.Presence.GetAsync();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 00:04:57