我目前正在使用GKE Workload Identity从GKE中访问Google Cloud Platform资源。这对于Google Cloud Storage和其他平台资源非常有效。
然而,当我尝试使用GKE工作负载标识来访问Google工作表时,我遇到了“身份验证范围不足”的问题。
当我为服务帐户生成密钥文件并在代码中使用它时,我可以手动将作用域设置为https://www.googleapis.com/auth/spreadsheets。它就像预期的那样工作,我可以访问工作表。如果我将作用域更改为https://www.googleapis.com/auth/cloud-platform,我会得到与GKE工作负载标识相同的错误,“身份验证作用域不足”。此结果显示服务帐户工作正常,因此问题似乎与分配给GKE工作负载标识的范围有关。
使用GKE工作负载标识,我使用credentials = google.auth.default() 1在Python中检索凭据。credentials对象具有预期的服务帐户,范围被设置为https://www.googleapis.com/auth/cloud-platform。我现在可以访问存储桶和服务帐户有权访问的其他云资源。然而,Google Sheets似乎需要https://www.googleapis.com/auth/spreadsheets作用域,但我还没有找到任何方法来设置它。工作负载标识(服务帐户)和范围是从GKE集群中运行的GKE元数据服务器检索的。据我所知,GKE工作负载标识的范围似乎是对https://www.googleapis.com/auth/cloud-platform进行了“硬编码”。我还没有找到关于这个是否可以改变的信息。
(我尝试将电子表格作用域添加到GKE节点oauth作用域。没有效果。根据我对文档的理解,这应该是无关的。)
(当然,我可以只使用一个密钥文件来完成这项工作,但GKE工作负载标识的全部要点正是为了避免安全地生成和分发密钥的所有麻烦)
发布于 2021-06-09 15:41:16
在google-auth指南中,您是否将电子表格范围设置为这样?
credentials, project = google.auth.default(
scopes=['https://www.googleapis.com/auth/spreadsheets'])我在使用默认客户机时看到了一些相同的行为,但在使用curl进行测试时,我确实在使用工作负载标识时取得了一些成功。
我们可以在测试pod上使用curl执行流程(例如,部署ubuntu pod并安装curl)。您应该能够通过卷曲GKE -metadata-server在gke pod上验证作用域内的令牌是否如您所期望的那样工作:
$ curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token?scopes=https%3A//www.googleapis.com/auth/spreadsheets%20然后,假设我们设置了ACCESS_TOKEN和SPREADSHEET_ID环境变量,我们可以像这样使用在对sheets API的请求中返回的令牌:
$ curl -X GET -H "Authorization: Bearer $ACCESS_TOKEN" https://sheets.googleapis.com/v4/spreadsheets/$SPREADSHEET_ID这将返回有关工作表的所有信息,而不是403错误。
我相信这就是客户端库应该在幕后做的事情,但这里可能有一些but。
以下是在配置了工作负载标识的GKE pod上运行的go应用程序的工作示例(服务帐户已被授予查看者访问工作表ID的权限)。
go.mod
module example.com/m
go 1.13
require (
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
google.golang.org/api v0.48.0
)main.go
package main
import (
"fmt"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/sheets/v4"
)
func main() {
client, err := google.DefaultClient(oauth2.NoContext, sheets.SpreadsheetsScope)
if err != nil {
panic(err)
}
srv, err := sheets.New(client)
if err != nil {
panic(err)
}
resp, err := srv.Spreadsheets.Values.Get("REPLACE_WITH_YOUR_SHEET_ID", "REPLACE_WITH_YOUR_RANGE").Do()
if err != nil {
panic(err)
}
fmt.Println(fmt.Sprintf("%+v", resp.Values))
}我注意到,使用旧版本的oauth2库肯定不能处理工作负载标识和作用域。更新以使用较新的版本解决了此问题。
发布于 2021-12-23 19:18:24
可以,停那儿吧。我不能重现你的问题,因为这(现在)是有效的:
import google
from googleapiclient.discovery import build
SHEET_ID = '<your_sheet_id>'
RANGE = 'Sheet1!A:Z'
credentials, project_name = google.auth.default()
service = build('sheets', 'v4', credentials=credentials).spreadsheets()
result = service.values().get(spreadsheetId=SHEET_ID, range=RANGE).execute()
print(result) # prints out the data in the sheet这是在运行v1.20.10-gke.1600的自动驾驶集群上进行测试的,其中在default KSA上设置了WLI,并在工作表上添加了相应的GSA-email作为Viewer。
请注意,我甚至没有设置任何作用域。您可能认为这是必需的:
google.auth.default(scopes=['https://www.googleapis.com/auth/spreadsheets'])`但它被完全忽略了:credentials.scopes = None
https://stackoverflow.com/questions/61238762
复制相似问题