我想读我的个人帐户的邮箱,但我得到"租户guid X的租户不存在".

  • 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

  • 然后,我使用以下代码获取令牌:

     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
         }
     }
    
  • 我用那个代码成功地得到了令牌

    {
         "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
     }
    
  • 然后我得到用户ID(我是唯一的用户):

     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
     }
    
  • 然而,当我试图收到这些邮箱时:

         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
         }
    

我得到了:

{
    "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上的错误是Tenand ID

推荐答案

要阅读personal Outlook帐号的邮件,您需要切换到delegated流,如交互流或授权码流,以生成访问令牌和呼叫/me/messages端点.

注册帐户类型为"Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)"的multi-tenant个应用程序:

enter image description here

如果您使用交互流生成令牌,请确保启用public client选项:

enter image description here

现在,根据您的需要,在您的应用注册中添加Delegated种类型的100101权限:

enter image description here

要使用交互流生成access token,您可以参考此示例GO代码,并在以后使用它来呼叫/me/messages端点:

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
}

您也可以使用该帐户登录100,然后运行以下查询以获取邮箱:

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

Go相关问答推荐

[0]Func()as";请勿比较哨兵类型

使用一元或服务器流将切片从GRPC服务器返回到客户端

golang 的持久隐蔽服务

错误&对象已被Golang在K8s操作符上修改

Golang telegram 机器人

一个Go module可以和之前的非module模块发布在同一个路径下吗?

在 Golang 模板中计算时间/持续时间

如何使用 fyne Go 使用 canvas.NewText() 使文本可滚动

如何将 npm 安装进度条通过管道传输到终端?

Golang Getrlimit 返回与 ulimit 不同的值

每次有人进入我的网站时如何运行特定功能?

为什么 0 big.Int 的 .Bytes() 值是空切片?

如何正确为 Go 中的值设置多种类型?

行之间的模板交替设计

如何将实际上是类型为 reflect.Int32 的类型切片的 interface{} 转换为 int32 的切片?

为什么在 goroutine 中声明时,benbjohnson/clock 模拟计时器不执行?

是否存在一个Go泛型类型约束,该约束捕获了将类型用作映射中的键的能力?

Gorilla/Mux 和 Websocket 竞赛条件,这安全吗?

Go 语言的select语句

Golang 中的无实体函数