为了为服务帐户创建密钥,这个定义有啥问题?

Posted

技术标签:

【中文标题】为了为服务帐户创建密钥,这个定义有啥问题?【英文标题】:What is wrong with this definition in order to create a key for a service account?为了为服务帐户创建密钥,这个定义有什么问题? 【发布时间】:2021-03-19 05:48:59 【问题描述】:

我已经实现了以下代码,但是每当我运行 Google 函数 HTTP 触发器时,我都会收到“错误:无法处理请求”错误。我检查了日志文件以查看错误(如下),但在它上面是我试图运行以获取密钥的代码。我想检索一个密钥,我可以使用它来测试它以连接到存储桶 - 这甚至可能吗???这是一种为某人提供密钥的方式,以便他们可以连接到存储桶并上传一些数据。我正在尝试复制 Azure 使用的 SAS,以便授予对存储帐户的访问权限。

service_account_email = 'demo@appspot.gserviceaccount.com'
    credentials = service_account.Credentials.from_service_account_file(
        filename=os.environ['GOOGLE_APPLICATION_CREDENTIALS'],
        scopes=['https://www.googleapis.com/auth/cloud-platform'])
    service = googleapiclient.discovery.build(
        'iam', 'v1', credentials=credentials)
    key = service.projects().serviceAccounts().keys().create(
        name='projects/-/serviceAccounts/' + service_account_email, body=
        ).execute()

newrequest 6dox145ag5e0 Traceback(最近一次调用最后一次):文件 "/env/local/lib/python3.7/site-packages/google/cloud/functions/worker_v2.py", 第 402 行,在 run_http_function 结果 = _function_handler.invoke_user_function(flask.request) 文件“/env/local/lib/python3.7/site-packages/google/cloud/functions/worker_v2.py”, 第 268 行,invoke_user_function 返回 call_user_function(request_or_event) 文件 "/env/local/lib/python3.7/site-packages/google/cloud/functions/worker_v2.py", 第 261 行,在 call_user_function 返回 self._user_function(request_or_event) 文件“/user_code/main.py”,行 33、在hello_world 文件名=os.environ['GOOGLE_APPLICATION_CREDENTIALS'],文件 “/env/lib/python3.7/os.py”,第 681 行,在 getitem 中引发 KeyError(key) from None KeyError: 'GOOGLE_APPLICATION_CREDENTIALS'

【问题讨论】:

你能解释一下你的用例吗?我了解到您希望即时创建密钥以让用户将数据下载和上传到 Cloud Storage,对吗? 你好纪尧姆。基本上我想要完成的是: - 用户只需转到 Google 函数的 URL 即可触发函数。该函数在存储桶中创建一个位置来存储数据。该函数还创建一个密钥,然后用户可以检索该密钥以连接到存储桶。我希望这个密钥可以让他们访问例如 googlebucket/companyname/。我希望这个功能只会创建一个允许他们访问该路径的密钥。 - 然后在他们连接后,用户上传数据,这会触发另一个功能来查看文件。我可以这样做吗? 【参考方案1】:

你可以这样做。但你不能这样做!

很多点:

您不能仅授予 Cloud Storage 上目录的权限。 (仅供参考,该目录不存在!它只是具有相同前缀的文件的聚合,并在 UI 中显示为这样。Cloud Storage 中有no "object" 目录)。 您仅限于10 keys per service account。 您在@appspot.gserviceaccount.com 中使用的服务帐户是 App Engine 默认服务帐户,默认情况下具有编辑者角色。很多许可,几乎可以在项目上做任何事情。如果你把它交给互联网上的某个人,它可能会破坏你的项目,甚至在带有比特币矿工的虚拟机上创建很多东西。你会付钱的!

正确的模式是:

用户使用凭据调用受保护的 Cloud Functions(如果您不知道使用什么以及如何操作,我们可以讨论这个问题)-> 不要让公开访问授予权限的函数! 使用 signedUrl 授予对特定 Cloud Storage 位置的访问权限,并在有限的时间内进行读取或写入操作。

更新 1:

要实现你想要的,你需要2个函数:

第一个提供signedUrl。部署您的 function in private mode --no-allow-unauthenticated(或从 Cloudfunctions.invoker 角色中删除 allUsers)。然后,当你测试时,你可以这样做curl -H "Authorization: Bearer $(gcloud auth print-access-token)" https:...。如果您使用外部工具,请使用命令gcloud auth print-access-token 生成令牌,将其复制并添加到请求的标头中。 1H有效。

第二个function will be triggered by Cloud Storage event。当文件被上传(最终确定)时,该函数将被调用。捕捉事件,从事件中获取文件元数据(桶名+文件路径)并存入数据库。

因为,我不知道你想对你的文件元数据做什么,所以我不能推荐一个数据库。

如果您有关系约束,请使用 Cloud SQL Firestore 是您的查询很简单(没有连接,没有复杂的过滤) 用于分析的 BigQuery

(有3个最实惠)

【讨论】:

好的,你已经说服我尝试其他方法。我现在想试试这个流程,你能建议使用什么 API 吗?创建一个 API 并为其设置身份验证。使用 Insomia/Fiddler 调用 API URL 并发送文件路径通过 Python 函数上传文件。将该文件作为二进制文件上传到数据库。如果可能的话,我应该设置什么数据库,我应该使用 Google 提供的特定 API?如果我应该创建另一个问题,请告诉我,我会的。 云函数会被其他服务或用户调用吗? (定义您需要的身份验证类型)。然后,我不明白文件存储。用户将文件上传到云存储。为什么要将文件作为二进制文件存储在数据库中?出于什么原因?这些数据将如何使用? 抱歉 Guillaume,我误解了我需要查找的请求。该文件不必作为二进制文件存储在数据库中,我只需要存储文件中的元数据。这是一个 POC,因此该函数只能由我调用。目前任何身份验证方法都可以。

以上是关于为了为服务帐户创建密钥,这个定义有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

我们可以为单个帐户创建多个 mws 访问权限和密钥吗?

在 Google API 中使用自定义帐户而不是服务帐户

加载服务帐户 Json 密钥文件

创建 GCP 服务帐户密钥时权限被拒绝

GCP IAM REST API 服务帐号密钥问题

使用自定义服务帐户在 GCP 中创建 VM 时,KMS 权限出现 400 错误