首页 > 解决方案 > MS Graph 外部用户 401 未经授权

问题描述

浏览类似问题后,我将尝试总结我的场景:

  1. 具有本机应用程序和管理员用户帐户的 Azure 租户。管理员帐户工作时从应用程序访问 MS Graph API。

  2. 我有一个 outlook.com 帐户,并且使用 MS Graph Explorer 可以阅读电子邮件。

  3. 我使用管理员帐户邀请外部 Outlook.com 帐户。我将此外部用户添加到应用程序的用户中,添加到 O365 订阅许可证中,我仔细检查了我从 Graph Explorer 中看到的相同授予权限,包括Mail.Readet al。已验证令牌具有这些权限。

  4. 我什至尝试让外部用户成为全局管理员进行测试,但是......使用 Outlook.com 凭据从本机应用程序中访问 MS Graph API 会产生401 Unauthorized.

  5. 如果我从本机应用程序复制完整的 URI 并粘贴到 MS Graph 中,它就可以工作。

这是我们的本机和网络应用程序调用代码:

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", token);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept
    .Add(new MediaTypeWithQualityHeaderValue("application/json"));

var requestUri = $"{MSGraphUtils.GraphResource}/{MSGraphUtils.VERSION}/{request}";
var response = await client.GetAsync(requestUri);
var responseContent = await response.Content.ReadAsStringAsync()

requestUri带有令牌并{request}附加为: https://graph.microsoft.com/v1.0/me/mailfoldersme/mailfolders/{id}/messages

而不是/me,我也试过了/users/{id|UPN}

如果我只发送https://graph.microsoft.com/v1.0/me,那么响应是正确的基本配置文件,但是一旦添加/mailfoldersor /messages,我就会得到401 Unauthorized

{
  "error": {
    "code": "UnknownError",
    "message": "",
    "innerError": {
      "request-id": "551340c6-1753-41d5-bc1a-e3ccdbc98e00",
      "date": "2018-05-24T13:48:23"
    }
  }
}

如果我使用令牌复制整个 requestUri 并将其直接粘贴到 Microsoft Graph Explorer 中,它将与/mailfolders.

scp还添加具有授予权限的令牌:

Calendars.ReadWrite 
Contacts.ReadWrite 
Files.ReadWrite.All 
Mail.Read 
Mail.ReadWrite 
Notes.ReadWrite.All 
People.Read 
Sites.Read.All 
Tasks.ReadWrite 
User.Read 
User.ReadBasic.All 
User.ReadWrite

获得令牌:

public static string Authority = "https://login.windows.net/common";
public static string GraphResource = "https://graph.microsoft.com";
public static string ReturnUri = "urn:ietf:wg:oauth:2.0:oob";

public static Task Authenticate(Account account)
{
    return Task.Run(async () =>

    var authContext = new AuthenticationContext(Authority);

    if (authContext.TokenCache.ReadItems().Any())
         authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority);

    var platformParams = new PlatformParameters(PromptBehavior.Auto);

    var result = await authContext.AcquireTokenAsync(GraphResource, CLIENT_ID, new Uri(ReturnUri), platformParams);

    if (result != null)
    {
       account.token = result.AccessToken;
    }
    });
}

标签: c#microsoft-graph-apioutlook-restapi

解决方案


当用户对您的租户进行身份验证时,您只能访问由您的租户控制的数据。换句话说,如果jdoe@outlook.com针对yourtenant.onmicrosoft.com租户进行身份验证,您将无法访问他们的outlook.com电子邮件。

您能够看到outlook.com来自 Graph Explorer 的电子邮件的原因是 Graph Explorer 正在针对他们的outlook.com帐户进行身份验证。换句话说,Graph Explorer 是jdoe@outlook.com针对outlook.com租户进行身份验证,而不是yourtenant.onmicrosoft.com.

当用户针对给定租户进行身份验证时,该令牌仅提供对该单个租户内数据的访问。Microsoft Graph 不允许您跨越租户边界。


推荐阅读