Search code examples
c#azureoutlookmicrosoft-graph-apimicrosoft-graph-mail

"The tenant for tenant guid does not exist" when using GraphAPI - Even with user type as Member


I am trying to access email using Microsoft Graph API. When I try to access the email I got the below error.

Microsoft.Graph.ServiceException: 'Code: OrganizationFromTenantGuidNotFound

Message: The tenant for tenant guid '<some id>' does not exist.

Here is the code to get the emails

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

var userId = "[email protected]"; // Tried [email protected] also
var messageId = "Actual message id";

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

Here is the code to get access token

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),
        new KeyValuePair<string, string>("Client_Id", _clientId),
        new KeyValuePair<string, 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();
}

I have searched in net for solutions. I found some solutions but none of them is working for me.

  1. User Type must be a Member. My user type is already Member. Original issue - “The tenant for tenant guid does not exist” even though user is listed on users endpoint?

    My User Type is Member

  2. Using Domain as tenentId. Its not working. Original issue - Getting "The tenant for tenant guid '' does not exist"

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

Some interesting observations

  • I was able to get the user but not their mails. Note: In this below code, only user id is working not their email id.

      var userId = "8685e56b-b1a8-45cf-a5d1-5c5ddadd0f3e"; 
      // EmailId ([email protected]) is not working here
      var user = await graphServiceClient.Users[userId].Request().GetAsync();
    
  • I found out that if I use the access token generated by Graph Explorer then my code is working properly. So probably the issue is in my GetAccessTokenAsync code or its configuration details.

Update:

I want to use Application permissions not Delegated permissions because my application will use Notification Subscriptions to get a notification when a new mail is received by any users. Also, I want to get the full email details of the new mail. In short, this application will run in the background.

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/[email protected]/messages",
    ChangeType = "created",
    ExpirationDateTime = DateTimeOffset.Now.AddDays(3).AddHours(-1),
    NotificationUrl = "https://asdasdasd.azurewebsites.net/Outlook/NewMailListener",
    ClientState = Guid.NewGuid().ToString()
});

Solution

  • It seems the problem was caused by you don't have O365 subscription. Although you have azure subscription and have an email for your azure account, but you do not have O365 subscription. So you can just get the users by graph but can not get email messages by graph.

    For this problem, you can just go to this page(login with you azure admin account) and buy O365 subscription.(for example: Office 65 E3) enter image description here

    Maybe you can also buy Exchange online(such as Exchange Online (Plan 2)) on the same page to access the email message.

    By the way, there is a mistake in your code. You use client_credentials as "Grant_Type" and use DelegateAuthenticationProvider. If you want to use DelegateAuthenticationProvider, you need to set "Grant_Type" as password but not client_credentials.

    To use client credential authentication, You need to install Microsoft.Graph.Auth. Note: this is a prerelease package. Here is a code snippet

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