Search code examples
azuregooutlookmicrosoft-graph-apimicrosoft-graph-mail

"The tenant for tenant guid X does not exist", for self email account(I'm the only member)


I would like to read email for my personal account but I'm getting "The tenant for tenant guid X does not exist".

  • I created an app using single tenant on https://entra.microsoft.com/ enter image description here

  • Then I assing it the permissions to email enter image description here

  • Then I created a client secret enter image description here

  • Then I use this code for getting the token:

     import(""github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential")
     cred, err := confidential.NewCredFromSecret("{secret value}")
     if err != nil {
         log.Println(err)
         return
     }
     confidentialClient, err := confidential.New("https://login.microsoftonline.com/{tenant id}", "{client id}", cred)
     if err != nil {
         log.Println(err)
         return
     }
     scopes := []string{"https://graph.microsoft.com/.default"}
     result, err := confidentialClient.AcquireTokenSilent(context.TODO(), scopes)
     if err != nil {
         result, err = confidentialClient.AcquireTokenByCredential(context.TODO(), scopes)
         if err != nil {
         log.Println(err)
             return
         }
     }
    
  • I successfully get the token with that code

    {
         "Account": {
             "AdditionalFields": null
         },
         "IDToken": {
             "RawToken": "",
             "AdditionalFields": null
         },
         "AccessToken": "{token}",
         "ExpiresOn": "2023-12-13T14:57:09.4905758-05:00",
         "GrantedScopes": [
             "https://graph.microsoft.com/.default"
         ],
         "DeclinedScopes": null
     }
    
  • Then I get the user id(I'm the only user):

     req, err := http.NewRequest("GET", "https://graph.microsoft.com/v1.0/users", nil)
     if err != nil {
         log.Println(err)
         return
     }
     req.Header.Add("Authorization", "{token}")
     client := http.Client{}
     resp, err := client.Do(req)
     if err != nil {
         log.Println(err)
         return
     }
     body, err := io.ReadAll(resp.Body)
     if err != nil {
         log.Println(err)
         return
     }
    
  • however when I try to get the emails:

         req, err := http.NewRequest("GET", "https://graph.microsoft.com/v1.0/users/{user_id}/messages", nil)
         if err != nil {
             log.Println(err)
             return
         }
         req.Header.Add("Authorization", "{token}")
         client := http.Client{}
         resp, err := client.Do(req)
         if err != nil {
             log.Println(err)
             return
         }
         body, err := io.ReadAll(resp.Body)
         if err != nil {
             log.Println(err)
             return
         }
    

I get:

{
    "error": {
        "code": "OrganizationFromTenantGuidNotFound",
        "message": "The tenant for tenant guid '0a6ac917-332a-4f47-881e-0b35fb1b2ab5' does not exist.",
        "innerError": {
            "oAuthEventOperationId": "c096c5c9-e743-4daa-9a97-d14d915e9842",
            "oAuthEventcV": "N0nHeUJm9gwnrFZefuEA4w.1.1",
            "errorUrl": "https://aka.ms/autherrors#error-InvalidTenant",
            "requestId": "c0272999-9743-44ee-98b5-947acc52e7d8",
            "date": "2023-12-13T19:11:22"
        }
    }
}

Id 0a6ac917-332a-4f47-881e-0b35fb1b2ab5 on the error is the tenand id


Solution

  • To read the mails of personal Outlook account, you need to switch to delegated flow like interactive flow or authorization code flow for generating access token and call /me/messages endpoint.

    Register multi-tenant application with account type as "Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)":

    enter image description here

    Make sure to enable public client option if you are using interactive flow for generating token:

    enter image description here

    Now, add Mail.Read or Mail.ReadWrite permission of Delegated type in your app registration based on your need:

    enter image description here

    To generate access token using interactive flow, you can refer this sample Go code and later use it for calling /me/messages endpoint:

    package public_test
    
    import (
        "context"
    
        "github.com/AzureAD/microsoft-authentication-library-for-go/apps/public"
    )
    
    func Example() {
        client, err := public.New("client_id", public.WithAuthority("https://login.microsoftonline.com/common"))
        if err != nil {
        }
    
        var result public.AuthResult
        scopes := []string{"https://graph.microsoft.com/.default"}
    
        accounts, err := client.Accounts(context.TODO())
        if err != nil {
            // TODO: handle error
        }
        if len(accounts) > 0 {
            result, err = client.AcquireTokenSilent(context.TODO(), scopes, public.WithSilentAccount(accounts[0]))
        }
        if err != nil || len(accounts) == 0 {
            result, err = client.AcquireTokenInteractive(context.TODO(), scopes)
            if err != nil {
            }
        }
        _ = result.Account
        _ = result.AccessToken
    }
    

    You can also sign into Graph Explorer with that account and run below query for getting emails:

    GET https://graph.microsoft.com/v1.0/me/messages
    

    Response:

    enter image description here

    Reference:

    microsoft-authentication-library-for-go/apps/public/example_test.go at main · AzureAD/microsoft-authentication-library-for-go · GitHub