【问题标题】:Cloud Endpoints returning 401 Jwt issuer is not configured返回 401 Jwt 颁发者的 Cloud Endpoints 未配置
【发布时间】:2020-07-01 01:33:56
【问题描述】:

我正在尝试设置服务到服务身份验证,以便外部应用程序可以向 Cloud Run 应用程序(在 Cloud Endpoints API 网关后面)发出请求。

我已遵循 Cloud Endpoints authentication between services 文档,但在尝试访问 Cloud Run 服务时仍收到以下错误:

401: 未配置 Jwt 颁发者

在 openapi 规范中,我设置了端点安全和 securityDefinition:

/endpoint_1:
  get:
     ...
     security:
       - service_account: []

securityDefinitions:
  service_account:
    authorizationUrl: ""
    flow: "implicit"
    type: "oauth2"
    x-google-issuer: "<service_account_email>"
    x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/<service_account_email>"
    x-google-audiences: "https://<cloud-run-service>-pjcfvhz2qq-uc.a.run.app"

然后使用 ESPv2 Beta 将其部署到 Cloud Run,如 Cloud Endpoints documentation 所述。

部署完所有内容后,我尝试从本地计算机运行以下脚本以生成签名的 jwt 并向 Cloud Run 服务发出请求:

import os
import json
import time
import requests
import google.auth.crypt
import google.auth.jwt

now = int(time.time())
expiry_length = 3600
sa_email = '<service_account_email>'

payload = {
    'iat': now,
    'exp': now + expiry_length,
    'iss': sa_email,
    'sub': sa_email,
    'email': sa_email,
    'aud': 'https://<cloud-run-service>-pjcfvhz2qq-uc.a.run.app',
}

file_path = "service-account.json"

signer = google.auth.crypt.RSASigner.from_service_account_file(file_path)
signed_jwt = google.auth.jwt.encode(signer, payload)

headers = {
    'Authorization': 'Bearer {}'.format(signed_jwt.decode('utf-8')),
    'content-type': 'application/json',
}

url = "https://<cloud-run-service>-pjcfvhz2qq-uc.a.run.app/endpoint_1"
res = requests.get(url, headers=headers)
print(res.json())

get 请求的响应:

{'message': 'Jwt issuer is not configured', 'code': 401}

已在 openapi 规范中将颁发者指定为与生成 JWT 时使用的颁发者匹配的服务帐户电子邮件。

任何关于未配置 Jwt 颁发者的实际含义的指导,我们不胜感激。

【问题讨论】:

  • @Chaos 在看到该帖子后,我曾尝试以 accounts.google.com 作为发行者,但没有成功。我也不确定它是否与服务帐户相关,而是与 firebase auth 提供的 id 令牌相关。
  • 我看到您基于 this information 的 OpenAPI 规范的 securityDefinitions: 字段。尽管如此,由于您使用的是 ESPv2 Beta,我认为您应该根据 documentation 更新这些规范。

标签: python jwt google-cloud-endpoints google-cloud-run


【解决方案1】:

我认为您需要 Google 签名的 JWT 令牌而不是自签名令牌。尝试使用此更改代码的结尾(在您的 signed_jwt = ... 行之后)

    auth_url = "https://www.googleapis.com/oauth2/v4/token"

    params = {
        'assertion': signed_jwt, # You may need to decode the signed_jwt: signed_jwt.decode('utf-8')
        "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
    }

    r = requests.post(auth_url, data=params)

    if r.ok:
        id_token = r.json()['id_token']

        headers = {
            'Authorization': 'Bearer {}'.format(id_token),
            'content-type': 'application/json',
        }

        url = "https://<cloud-run-service>-pjcfvhz2qq-uc.a.run.app/endpoint_1"
        res = requests.get(url, headers=headers)
        print(res.json())

    # For debugging
    print(r)
    print(vars(r))

【讨论】:

    【解决方案2】:

    您是否部署了带有“--allow-unauthenticated”标志的 ESPv2 Cloud-Run 服务?如果否,ESPv2 云运行服务受 IAM 服务器保护,它将验证 JWT 令牌并将新令牌传递给 ESPv2。 ESPv2 将无法从新令牌中识别其发行者。

    为了使 ESPv2 JWT 身份验证正常工作,您必须通过在“gcloud run deploy”命令中传递标志“--allow-unauthenticated”来禁用 ESPv2 cloud-run 的 IAM。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-29
      • 2021-11-27
      • 2017-04-26
      • 1970-01-01
      • 1970-01-01
      • 2015-03-13
      • 2018-12-31
      • 2019-08-29
      相关资源
      最近更新 更多