英文:
Domain wide delegation with default credentials in Cloud Run
问题
在golang中,我想使用Cloud Run提供的默认服务帐号凭据来创建委派凭据(域范围委派),具体来说是以用户身份调用Drive API。当凭据从JSON文件获取时,我已经成功实现了这一点,但是当凭据由Cloud Run提供时却没有成功。我在Python中遇到了同样的问题,并按照这个示例解决了它,但是我不确定如何在go中实现。
以下是一个示例代码(gin处理程序),当从JSON文件加载时可以工作(具有域范围委派的服务帐号密钥),但是当从Cloud Run派生凭据时无法工作:
email := "user@mydomain.com"
params := google.CredentialsParams{
Scopes: []string{"https://www.googleapis.com/auth/drive.readonly"},
Subject: email}
creds, credErr := google.FindDefaultCredentialsWithParams(c, params)
if credErr != nil {
msg := fmt.Sprintf("Unable to create credentials as %v: %v", email, credErr)
fmt.Println(msg)
c.String(http.StatusInternalServerError, msg)
return
}
// CREATE DRIVE SERVICE
client := oauth2.NewClient(c, creds.TokenSource)
driveService, driveErr := drive.NewService(c, option.WithHTTPClient(client))
if driveErr != nil {
msg := fmt.Sprintf("Unable to retrieve Drive client: %v", driveErr)
fmt.Println(msg)
c.String(http.StatusInternalServerError, msg)
return
}
// List Files
r, listErr := driveService.Files.List().PageSize(10).Do()
if listErr != nil {
log.Fatal(listErr)
}
fmt.Printf("Received %v files\n", len(r.Files))
for _, i := range r.Files {
fmt.Println(i.Name)
}
c.String(http.StatusOK, "Ok")
return
当我从JSON文件运行时,它会列出来自user@mydomain.com的十个文件名。当我在Cloud Run中运行时(不在容器中包含JSON文件),它找不到任何文件,我认为这是因为凭据不是用户凭据,而是没有访问任何文件权限的服务帐号凭据。
英文:
In golang I'd like to use default service account credentials provided by Cloud Run to create delegated credentials (domain-wide delegation), specifically to invoke the Drive API as the user. I've got this working when the credentials are obtained from a json file, but not when provided by Cloud Run. I had the same problem in Python and followed this example to solve it, but am not sure how to do this in go.
Code example (gin handler) that works when loading from JSON file (service account key with domain-wide delegation) but not when deriving credentials from Cloud Run:
email := "user@mydomain.com"
params := google.CredentialsParams{
Scopes: []string{"https://www.googleapis.com/auth/drive.readonly"},
Subject: email}
creds, credErr := google.FindDefaultCredentialsWithParams(c, params)
if credErr != nil {
msg := fmt.Sprintf("Unable to create credentials as %v: %v", email, credErr)
fmt.Println(msg)
c.String(http.StatusInternalServerError, msg)
return
}
// CREATE DRIVE SERVICE
client := oauth2.NewClient(c, creds.TokenSource)
driveService, driveErr := drive.NewService(c, option.WithHTTPClient(client))
if driveErr != nil {
msg := fmt.Sprintf("Unable to retrieve Drive client: %v", driveErr)
fmt.Println(msg)
c.String(http.StatusInternalServerError, msg)
return
}
// List Files
r, listErr := driveService.Files.List().PageSize(10).Do()
if listErr != nil {
log.Fatal(listErr)
}
fmt.Printf("Received %v files\n", len(r.Files))
for _, i := range r.Files {
fmt.Println(i.Name)
}
c.String(http.StatusOK, "Ok")
return
When I run this from JSON file, it lists the ten file names from user@mydomain.com. When I run this in Cloud Run (without including the JSON file in the container), it doesn't find any files, and I believe this is because the credentials are not user credentials, but rather service account credentials without access to any files.
答案1
得分: 2
要在没有服务帐号密钥的情况下使用域范围委派,您需要执行以下步骤:
- 创建一个JWT断言,用于模拟用户身份。具体步骤可以参考此链接。
- 调用配置了域范围委派的服务帐号上的
projects.serviceAccounts.signJwt
接口,对断言进行签名。更多信息可以参考此链接。 - 使用签名后的断言来交换访问令牌。
英文:
To use domain-wide delegation without a service account key you have to:
- Create a JWT assertion for impersonating a user
- Call projects.serviceAccounts.signJwt on a service account that's configured for domain-wide delegation to sign the assertion
- Exchange the signed assertion against an access token
This blog post and this question have more details.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论