Я хочу запросить 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.Как еще я могу выполнить делегирование?