我想查询GSuite Admin SDK Directory API以返回Go中一个组中的所有用户,并通过GCP服务帐户身份验证(脚本将在Google Compute Engine VM或作为Google Cloud Function)。
我使用的服务帐户(我们称其为my-service-account@my-project.iam.gserviceaccount.com
)已在GSuite中获得了必要的范围:
我还有一个GSuite Admin 帐户(我们将其称为my-admin@my-domain.com
)。该帐户将用于授权(请参见the docs on delegation)。
我可以使用以下代码返回一个组中的所有用户(基于上面提供的链接中的代码,并且我删除了大多数错误处理,以使代码更短):
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
}
如您所见,该代码必须具有my-service-account@my-project.iam.gserviceaccount.com
的JSON密钥文件。这是我发现创建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
中的所有用户。
但是,由于此代码将从使用my-service-account@my-project.iam.gserviceaccount.com
作为服务帐户的Google Compute Engine VM(或Google Cloud Function)运行,因此需要JSON密钥似乎很可笑该服务帐户的身份进行身份验证(因为我已经在VM或GCF内部以my-service-account@my-project.iam.gserviceaccount.com
身份进行身份验证)。
我尝试用以下代码替换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
由于这是我删除代表团时遇到的相同错误,因此我认为这是相关的。实际上,在admin.Service
创建期间,我没有在任何地方提供我的GSuite管理员帐户。
任何人都可以帮助您解决以下问题之一:
jwt.Config
对象吗?golang.org/x/oauth2/google
的源代码,可以得到oauth2.Config
而不是jwt.Config
,但是似乎不可能用oauth2令牌“委托”。我还能如何执行委派?答案 0 :(得分:0)
这篇文章有点旧,但希望能帮到你:
我遇到了同样的问题,并通过更改计算实例中的 OAuth 范围使其工作(默认情况下,范围仅包括 https://www.googleapis.com/auth/cloud-platform
)。就我而言,我必须添加 https://www.googleapis.com/auth/admin.directory.group.readonly
范围。可以使用 gcloud compute instances set-service-account
命令来完成。这样,从元数据服务器收到的服务帐户不记名令牌就具有访问 Admin Directory API 的正确范围。
遗憾的是,它无法为 Cloud Functions 完成,因为 Cloud Functions OAuth 范围似乎不可自定义。
有关详细信息,请参阅 this post。
顺便说一句,现在还可以授予服务帐户访问 Admin Directory API without domain-wide delegation 的权限。
答案 1 :(得分:-1)
r, err := srv.Users.List().
ViewType("domain_public").
Customer("my_customer").
OrderBy("email").
Do()
尝试使用它。