使用 Google Cloud Platform 服务帐户查询 GSuite Directory API

nor*_*bjd 7 go jwt google-cloud-platform google-workspace

我想查询GSuite Admin SDK Directory API以返回组中的所有用户,在 Go 中,并作为 GCP 服务帐户进行身份验证(该脚本将在 Google Compute Engine VM 中或作为 Google Cloud Function 执行)。

我使用的服务帐户(我们称之为my-service-account@my-project.iam.gserviceaccount.com)已在 GSuite 中被授予必要的范围:

我还有一个 GSuite管理员帐户(我们称之为my-admin@my-domain.com)。该帐户将用于委派(请参阅有关委派的文档)。

我可以使用以下代码返回组中的所有用户(基于上面提供的链接中的代码,并且我删除了大部分错误处理以使代码更短):

package main

import (
    "io/ioutil"
    "log"
    "os"

    "golang.org/x/net/context"
    "golang.org/x/oauth2/google"
    admin "google.golang.org/api/admin/directory/v1"
)

func main() {
    srv := createAdminDirectoryService(
        os.Getenv("SERVICE_ACCOUNT_FILE_PATH"),
        os.Getenv("GSUITE_ADMIN_USER_EMAIL"),
    )
    members := listUsersInGroup(srv, os.Args[1])
    log.Println(members)
}

func createAdminDirectoryService(serviceAccountFilePath,
                                 gsuiteAdminUserEmail string) *admin.Service {
    jsonCredentials, _ := ioutil.ReadFile(serviceAccountFilePath)

    config, _ := google.JWTConfigFromJSON(
        jsonCredentials,
        admin.AdminDirectoryGroupMemberReadonlyScope,
    )
    config.Subject = gsuiteAdminUserEmail

    ctx := context.Background()
    client := config.Client(ctx)

    srv, _ := admin.New(client)
    return srv
}

func listUsersInGroup(srv *admin.Service, groupEmail string) []string {
    members, err := srv.Members.List(groupEmail).Do()
    if err != nil {
        log.Fatal(err)
    }

    membersEmails := make([]string, len(members.Members))
    for i, member := range members.Members {
        membersEmails[i] = member.Email
    }

    return membersEmails
}
Run Code Online (Sandbox Code Playgroud)

如您所见,该代码需要有一个 .json 密钥文件my-service-account@my-project.iam.gserviceaccount.com。这是我发现创建jwt.Config对象的唯一方法。

此外,请注意,授权是通过以下行完成的config.Subject = gsuiteAdminUserEmail;如果没有这个,我得到了错误:

googleapi: Error 403: Insufficient Permission: Request had insufficient authentication scopes., insufficientPermissions
Run Code Online (Sandbox Code Playgroud)

无论如何,运行:

SERVICE_ACCOUNT_FILE_PATH=/path/to/json/key/of/my/service/account \
GSUITE_ADMIN_USER_EMAIL=my-admin@my-domain.com \
go run main.go my-group@my-domain.com
Run Code Online (Sandbox Code Playgroud)

成功打印 中的所有用户my-group@my-domain.com

然而,由于此代码将从用作服务帐户的 Google Compute Engine VM(或 Google Cloud Function)运行my-service-account@my-project.iam.gserviceaccount.com,因此需要该服务帐户的 JSON 密钥进行身份验证似乎很荒谬(因为我已经通过身份验证为my-service-account@my-project.iam.gserviceaccount.com,在VM 或 GCF 内部)。

我尝试createAdminDirectoryService()用以下代码替换内容,以作为启动脚本的用户进行身份验证(使用默认凭据):

func createAdminDirectoryService() *admin.Service {
    ctx := context.Background()

    client, _ := google.DefaultClient(ctx, scopes...)

    srv, _ := admin.New(client)
    return srv
}
Run Code Online (Sandbox Code Playgroud)

但列出用户会返回错误:

googleapi: Error 403: Insufficient Permission: Request had insufficient authentication scopes., insufficientPermissions
Run Code Online (Sandbox Code Playgroud)

由于这与我删除委托时遇到的错误相同,因此我认为这是相关的。事实上,我在创建过程中没有在任何地方提供我的 GSuite 管理员帐户admin.Service

任何人都可以帮助解决以下几点之一:

  • 如何直接向在 Google Compute Engine VM 或 Google Cloud Function 上运行 go 脚本的用户进行身份验证?
  • 我真的需要 JSON 密钥文件来生成jwt.Config对象吗?
  • 我查看了 的源代码golang.org/x/oauth2/google,我可以得到 aoauth2.Config而不是jwt.Config,但似乎不可能用 oauth2 令牌“委托”。我还能如何执行委托?

小智 -1

    r, err := srv.Users.List().
        ViewType("domain_public").
        Customer("my_customer").
        OrderBy("email").
        Do()
Run Code Online (Sandbox Code Playgroud)

Try using this.

  • 嘿,欢迎来到堆栈溢出!考虑添加更多细节,说明为什么你的答案会有效,或者提问者哪里不正确。 (2认同)