使用GraphAPI时“租户guid的租户不存在”-即使用户类型为Member

问题描述

我正在尝试使用Microsoft Graph API访问电子邮件。当我尝试访问电子邮件时,出现以下错误

Microsoft.Graph.ServiceException:'代码:OrganizationFromTenantGuidNotFound

消息:承租人guid''的承租人不存在。

这是获取电子邮件代码

var graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider((requestMessage) =>
{
    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer",accesstoken);
    return Task.CompletedTask;
}));

var userId = "quicksilverconnect@outlook.com"; // Tried [email protected] also
var messageId = "Actual message id";

var email = await graphServiceClient.Users[userId].Messages[messageId].Request().GetAsync();

这是获取访问令牌的代码

private const string _clientId = "xxxxxxx-xxxxxx-xxxxxxx-xxxx";
private const string _clientSecret = "xxxxxxx-xxxxxx-xxxxxxx-xxxx";
private const string _tenantName = "ecd90453-34b6-xxxx-xxxx-xxxxxxxxx";
private readonly string _uri = $"https://login.microsoftonline.com/{_tenantName}/oauth2/v2.0/token";
private const string _grantType = "client_credentials";
private const string _scope = "https://graph.microsoft.com/.default";

public async Task<string> GetAccesstokenAsync()
{
    var content = new FormUrlEncodedContent(new[]
    {
        new keyvaluePair<string,string>("Grant_Type",_grantType),new keyvaluePair<string,string>("Scope",_scope),string>("Client_Id",_clientId),string>("Client_Secret",_clientSecret)
    });
    var responce = await _httpClient.PostAsync(_uri,content);

    responce.EnsureSuccessstatusCode();

    var jsonString = await responce.Content.ReadAsstringAsync();

    var document = await JsonDocument.ParseAsync(jsonString.ToStream());

    return document.RootElement.GetProperty("access_token").GetString();
}

我已经在网上搜索解决方案。我找到了一些解决方案,但没有一个我有用。

  1. 用户类型必须是成员。我的用户类型已经是会员。原始问题-“The tenant for tenant guid does not exist” even though user is listed on users endpoint?

    My User Type is Member

  2. 使用域作为tenentId。它不起作用。原始问题-Getting "The tenant for tenant guid '' does not exist"

     private const string _tenantName = "quicksilverconnectoutlook.onmicrosoft.com";
    

一些有趣的发现

  • 我能够收到用户,但无法收到他们的邮件。注意:在下面的这段代码中,只有用户ID起作用,而其电子邮件ID起作用。

      var userId = "8685e56b-b1a8-45cf-a5d1-5c5ddadd0f3e"; 
      // EmailId (quicksilverconnect@outlook.com) is not working here
      var user = await graphServiceClient.Users[userId].Request().GetAsync();
    
  • 我发现,如果我使用Graph Explorer生成的访问令牌,则我的代码可以正常工作。因此,问题可能出在我的GetAccesstokenAsync代码或其配置详细信息中。

更新:

我想使用应用程序权限而不是委派权限,因为当任何用户收到新邮件时,我的应用程序将使用“通知订阅”来获取通知。另外,我想获得新邮件的完整电子邮件详细信息。简而言之,该应用程序将在后台运行。

var graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider((requestMessage) =>
{
    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer",accesstoken);
    return Task.CompletedTask;
}));

var subscription = await graphServiceClient.Subscriptions.Request().AddAsync(new Subscription()
{
    Resource = "/users/quicksilverconnect@outlook.com/messages",ChangeType = "created",ExpirationDateTime = DateTimeOffset.Now.AddDays(3).AddHours(-1),NotificationUrl = "https://asdasdasd.azurewebsites.net/Outlook/NewMailListener",ClientState = Guid.NewGuid().ToString()
});

解决方法

问题似乎是由于您没有O365订阅引起的。尽管您具有天蓝色订阅,并且具有用于天蓝色帐户的电子邮件,但是您没有O365订阅。因此,您只能按图获取用户,而不能按图获取电子邮件。

对于此问题,您可以转到此page(使用您的azure管理员帐户登录)并购买O365订阅。(例如:Office 65 E3enter image description here

也许您也可以在同一页面上在线购买Exchange(例如Exchange Online (Plan 2))以访问电子邮件。

顺便说一句,您的代码有错误。您将client_credentials用作“ Grant_Type ”并使用DelegateAuthenticationProvider。如果要使用DelegateAuthenticationProvider,则需要将“ Grant_Type ”设置为password,而不是client_credentials

要使用客户端凭据身份验证,您需要安装Microsoft.Graph.Auth。注意:这是一个预发行包。这是一个代码段

var confidentialClientApplication = ConfidentialClientApplicationBuilder
                                            .Create(configuration.ClientId)
                                            .WithTenantId(configuration.TenantId)
                                            .WithClientSecret(configuration.ClientSecret)
                                            .Build();
var authProvider = new ClientCredentialProvider(confidentialClientApplication);
var graphServiceClient = new GraphServiceClient(_clientCredentialProviderauthProvider);