【问题标题】:Google Cloud Function authentication. Obtain Identity token authorization bearer header curl谷歌云功能认证。获取身份令牌授权承载头 curl
【发布时间】:2019-12-29 05:22:31
【问题描述】:

基于 cron 样式部署设置 pub/sub 以调用 google 函数,该函数将检查新数据,然后将其推送到管道。此管道的一部分需要提交带有授权标头的 curl 调用,该授权标头采用身份令牌。我还没有找到生成此身份令牌的好方法。

我目前尝试将云功能的所有者更改为具有跨存储/数据标签/云功能权限的服务帐户,并且我还使用了带有私钥的存储凭证文件(即access.json)。我有一个指向此私钥的环境变量集 (GOOGLE_APPLICATION_CREDENTIALS),并尝试通过 $(gcloud auth application-default print-access-token) 在谷歌云函数中提取身份令牌 - 这将返回一个没有错误的空字符串。

# I have tried something very similar to this

command = "echo $(gcloud auth application-default print-access-token)"
p = subprocess.Popen(command, shell=True, 
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE)
p.wait()
out = p.communicate()
print("OUT_CODE: ", out)

我只是想用正确获得的令牌提交这个 curl 命令。

command = "GOOGLE_APPLICATION_CREDENTIALS=/user_code/dl_access.json bash -c 'gcloud auth activate-service-account --key-file=/user_code/dl_access.json; echo $(gcloud auth application-default print-access-token)'"
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
p.wait()
out, err = p.communicate()
auth = out.decode().rstrip()
print("OUT_CODE: ", out, err)
command = "curl -X POST "
command += '-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" '
command += '-H "Content-Type: application/json" '
command += 'https://datalabeling.googleapis.com/v1beta1/projects/'
command += '{}/datasets/{}/image:label '.format(PROJECT_ID, dataset.name.split("/")[-1])
command += "-d '{"
command += '"basicConfig": {'
command += '"labelGroup": "{}", '.format("test_label_group")
command += '"instruction": "{}", '.format("projects/cv/instructions/5cd5da11_0sdfgsdfgsdfg2c0b8eb8")
command += '"annotatedDatasetDisplayName": "{}", '.format(dataset.display_name)
command += '"replica_count": 3 '
command += '}, '
command += '"feature": "BOUNDING_BOX", '
command += '"boundingPolyConfig": { '
command += '"annotationSpecSet": "{}", '.format(
    "projects/cv/annotationSpecSets/_b3b1_005csdfgc6_0000_297e1a11439bdc")
command += '}, '
command += "}' "

print(command)
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
p.wait()
out, err = p.communicate()
print("out:", out)
print("err:", err)

由于Authorization: Bearer <ID_Token>ID_Token 的空字符串,上述操作失败。

【问题讨论】:

    标签: python-3.x google-cloud-platform google-cloud-functions google-oauth


    【解决方案1】:

    您的云功能已被沙盒化,您无法执行系统调用。请记住,您处于无服务器模式,您不知道底层服务器有什么问题:它自己的问题是什么?是否安装了 gcloud 和 curl?哪个版本?....

    因此,您必须编写代码并进行 Python 调用。查看libraries for data labeling。 如果您更喜欢直接调用 API,也可以从 function to function 代码中获得灵感。

    【讨论】:

      【解决方案2】:

      不要在 Cloud Functions 中使用 shell 脚本、外部命令等。

      以下是在 Cloud Functions 中运行时如何获取 OAuth 2.0 身份令牌的示例。在您的真实代码中,您需要将“audience”值更改为您调用的服务所需的任何值。如果您调用此函数,它将在您的浏览器中显示“SUCCESS”或“FAILURE”。此代码还演示了如何使用 Python requests 库发出 HTTP 请求。使用这个库而不是尝试执行 CURL 程序。

      import requests
      import json
      
      def entry(request):
          id_token = requestIdentityToken('http://www.example.com')
      
          if id_token is not None:
              print('ID Token', id_token)
              return f'SUCCESS'
          else:
              return f'FAILURE'
      
      def requestIdentityToken(audience=None):
              host = 'http://metadata.google.internal'
              header = {'Metadata-Flavor': 'Google'}
      
              if audience is None:
                      audience = 'http://example.com'
      
              url = '{}/computeMetadata/v1/instance/service-accounts/default/identity?audience={}'.format(host, audience)
      
              try:
                      r = requests.get(url=url, headers=header)
      
                      if r.status_code < 200 or r.status_code >= 300:
                              print('Error:', r.reason)
                              return None
      
                      return r.text
              except Exception as e:
                      print(str(e))
                      return None
      

      部署此功能的示例命令:

      gcloud functions deploy requestIdentityToken --runtime python37 --trigger-http --entry-point entry
      

      此命令将“打印”您将在 Stackdriver 日志中找到的用于此功能的身份令牌。

      附加信息:

      【讨论】:

        猜你喜欢
        • 2016-04-13
        • 2020-12-28
        • 1970-01-01
        • 2018-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-27
        相关资源
        最近更新 更多