【问题标题】:Microsoft Graph API daemon - Error: ResourceNotFound Message: Resource could not be discoveredMicrosoft Graph API 守护程序 - 错误:ResourceNotFound 消息:无法发现资源
【发布时间】:2020-05-01 11:31:51
【问题描述】:

我正在尝试使用 Microsoft Graph API v1.0 创建一个守护程序。
我已在获得管理员同意的情况下使用应用程序权限 Calendars.ReadWrite 和 User.Read.All 注册了我的应用程序。
我正确获取了访问令牌,并调用了 GetUserId,它返回用于设置 requestURI 的用户 ID。
之后我想检索 Outlook 日历:

var id = await GetUserId(result.AccessToken);

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

String requestURI = $"https://graph.microsoft.com/v1.0/users/{id}/calendars";

var response = await httpClient.GetAsync(requestURI);
var responseString = await response.Content.ReadAsStringAsync();

但我收到此错误:

{
  "error": {
    "code": "ResourceNotFound",
    "message": "Resource could not be discovered.",
    "innerError": {
      "request-id": "5ecd547b-9281-4824-94e5-095691e759aa",
      "date": "2020-01-14T16:44:16"
    }
  }
}

当我将requestURI 设置为users/{id}organization 时,请求工作正常,但添加/calendars/events/mailFolder 会导致上述错误。

我认为我的问题是我使用了个人帐户。我需要使用工作或学校帐户吗?是否可以使用个人帐户?我的错误还有其他原因吗?

更新:检索令牌的代码:

app = ConfidentialClientApplicationBuilder
    .Create(ClientId)
    .WithClientSecret(ClientSecret)
    .WithAuthority($"https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token&grant_type=client_credentials&resource=https://graph.microsoft.com")
    .Build();
string[] scopesClient =
    new string[] { $"https://graph.microsoft.com/.default" };
AuthenticationResult result = null;
try
{
    result = await app.AcquireTokenForClient(scopesClient).ExecuteAsync();
}
catch (MsalServiceException ex) when(ex.Message.Contains("AADSTS70011"))
{

}

【问题讨论】:

  • 你是如何获得代币的,你所说的“个人账户”是什么意思?根据日志,此令牌是由 AAD 租户使用 User.Read.AllCalendar.ReadWrite 应用程序范围发出的。如果您使用的是 Outlook.com 帐户,则该令牌将仅支持委托范围。
  • 感谢@Mark 回复。这是获取token的代码
    app =ConfidentialClientApplicationBuilder.Create(ClientId).WithClientSecret(ClientSecret).WithAuthority($"https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token&grant_type=client_credentials&resource=https://graph.microsoft.com").Build(); string[] scopesClient=new string[] { $"https://graph.microsoft.com/.default" }; AuthenticationResult result = null; try { result = await app.AcquireTokenForClient(scopesClient).ExecuteAsync(); }catch (MsalServiceException ex) when(ex.Message.Contains("AADSTS70011")){}
  • 我使用 Outlook.com 帐户和非 Outlook.com 帐户都收到上述错误。

标签: c# asp.net-web-api microsoft-graph-api microsoft-graph-mail microsoft-graph-calendar


【解决方案1】:

文档说明您必须同时添加 CalenderRead 和 CalenderReadWrite。如果没有,如果您使用的是个人帐户,我将使用委派权限。我还会去 ms.jwt,他们在那里检查您的令牌并告诉您您拥有什么权限以及您需要调用日历端点什么

【讨论】:

  • 非常感谢@Ashok Subedi 的回复。我在授予管理员同意的情况下添加了 CalendarRead 权限,但错误是相同的。正如你所说,我还在 jwt.ms 中检查了我的令牌,看起来没问题:在角色数组中,我有“Calendars.Read”、“User.Read.All”和“Calendars.ReadWrite”。还有其他建议吗?
  • 你能给我一个完整的api吗?是给你一个错误。
【解决方案2】:

你是 Authority 不太正确:

  1. resource=https://graph.microsoft.com 是旧设置,不用于 v2 Endpoint(也就是使用 Scopes 而不是资源进行身份验证)。

  2. ConfidentialClientApplicationBuilderhandes 自动设置 OAuth 授权,因此不需要指定 grant_type=client_credentials

  3. 授权应该只包含认证授权 (https://login.microsoftonline.com/) 和租户 ID。处理此问题的最简单方法是使用 AzureCloudInstance.AzurePublic 枚举

您的令牌代码应如下所示:

app = ConfidentialClientApplicationBuilder
    .Create(ClientId)
    .WithClientSecret(ClientSecret)
    .WithAuthority(AzureCloudInstance.AzurePublic, TenantId)
    .Build();

string[] scopes = new string[] { "https://graph.microsoft.com/.default" };

AuthenticationResult result = null;
try
{
    result = await app
        .AcquireTokenForClient(scopes)
        .ExecuteAsync();
}
catch (MsalServiceException ex)
{

}

注意:您将无法通过@outlook.com 帐户使用此方法。个人账户不支持client_credentials

【讨论】:

  • 谢谢马克。我按照你说的修改了我的代码,但结果是一样的。我将 requestURI 修改为 graph.microsoft.com/beta 并收到错误代码“MailboxNotEnableForRESTAPI”。我的问题是否可能取决于已发布的令牌?
  • 该错误表明您要连接的两个帐户要么没有许可/配置的邮箱,要么没有使用 Exchange Online。不支持本地和混合配置。
【解决方案3】:

为了调用 /{user-id}/events、/calendar 或 /mailFolder 工作,如果您将客户端凭据用于 Daemon 应用程序,用户必须在 Exchange Online 上拥有邮箱。

当许可证为组织用户时,我们通常会收到此 {"error":{"code":"ResourceNotFound","message":"Resource could not be found."}} 错误未分配给用户或未为他们配置邮箱。

在 Microsoft 个人帐户中,用户没有邮箱(这对 null 值有意义,如下所示),因此呼叫不起作用。

似乎无法将许可证分配给访客帐户(在本例中为 Microsoft 个人帐户),因此用户帐户永远无法访问日历服务(o365 在线交换的一部分)。导致无法检索个人 Outlook 帐户的日历信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    相关资源
    最近更新 更多