Запрос API-интерфейса GSuite с учетной записью службы Google Cloud Platform - PullRequest
3 голосов
/ 26 апреля 2019

Я хочу запросить GSuite Admin API SDK Directory , чтобы вернуть всех пользователей в группе, в Go, и , аутентифицированных как учетная запись службы GCP (скрипт будет выполнен вВиртуальная машина Google Compute Engine или как облачная функция Google).

Используемой учетной записи службы (назовем ее my-service-account@my-project.iam.gserviceaccount.com) предоставлены необходимые области в GSuite:

В моем распоряжении также есть GSuite Admin аккаунт (назовем его 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
}

Как видите, этот код требует наличия файла ключа 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

В любом случае, запустив:

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

с успехом печатает всех пользователей в my-group@my-domain.com.

Однако, поскольку этот код будет запускаться с виртуальной машины Google Compute Engine (или облачной функции Google) с my-service-account@my-project.iam.gserviceaccount.com, используемой в качестве учетной записи службы, кажется нелепым, чтобы для аутентификации требовался ключ JSON этой учетной записи службы (поскольку яуже аутентифицирован как my-service-account@my-project.iam.gserviceaccount.com, на виртуальной машине или внутри GCF).

Я попытался заменить содержимое createAdminDirectoryService() следующим кодом, чтобы аутентифицироваться как пользователь, запустивший скрипт (с учетными данными по умолчанию)):

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

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

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

Но перечисление пользователей возвращает ошибку:

googleapi: Error 403: Insufficient Permission: Request had insufficient authentication scopes., insufficientPermissions

Поскольку это та же ошибка, что и при удалении делегирования, я думаю, что это связано.Действительно, я нигде не предоставлял свою учетную запись администратора GSuite при создании admin.Service.

Может ли кто-нибудь помочь с одним из следующих пунктов:

  • Как я могу аутентифицироваться непосредственно с пользователемзапустить скрипт go на виртуальной машине Google Compute Engine или в облачной функции Google?
  • Нужен ли мне файл ключа JSON для создания jwt.Config объекта?
  • Я изучилИсходный код golang.org/x/oauth2/google, я мог бы получить oauth2.Config вместо jwt.Config, но не представляется возможным "делегировать" с помощью токена oauth2.Как еще я могу выполнить делегирование?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...