0

我正在尝试通过 Google Cloud API Gateway 中的 JWT 实现用户身份验证。我已根据文档
在 API 配置中配置了安全要求对象和安全定义对象

securityDefinitions:
    google_id_token:
      authorizationUrl: ""
      flow: "implicit"
      type: "oauth2"
      x-google-issuer: "https://accounts.google.com"
      x-google-jwks_uri: "https://www.googleapis.com/oauth2/v3/certs"
security:
   - google_id_token: []

后端服务是 Cloud Run 服务

x-google-backend:
  address: https://my-apis-fskhw40mta-uk.a.run.app

但是,当我使用我的用户持有者令牌调用 API 时,我收到 403 错误,并且堆栈驱动程序日志中出现此错误

"jwt_authn_access_denied{Audiences_in_Jwt_are_not_allowed}"

调用 API 的 Python 客户端代码是

id_token = subprocess.run(['gcloud', 'auth',  'print-identity-token'], capture_output=True, text=True, shell=True).stdout

http = urllib3.PoolManager()
encoded_args = urlencode({'arg1': "val1"})
r = http.request(
    'GET',
    API_URL + "/run-api?" + encoded_args,
    headers={"Authorization": f"Bearer {id_token}"}
)

使用用户帐户(不是服务帐户)时包含受众的正确方法是什么

更新 1
我找到了一种方法,但我不确定它是否正确。如果我添加32555940559.apps.googleusercontent.comsecurityDefinitionsso 它看起来像这样

securityDefinitions:
    google_id_token:
      authorizationUrl: ""
      flow: "implicit"
      type: "oauth2"
      x-google-issuer: "https://accounts.google.com"
      x-google-jwks_uri: "https://www.googleapis.com/oauth2/v3/certs"
      x-google-audiences: "https://oauth2.googleapis.com/token, 32555940559.apps.googleusercontent.com"

它将允许未经身份验证访问 Cloud Run,但是我仍然无法在启用身份验证的情况下调用 Cloud Run。403由于 API 网关服务帐号没有权限,Cloud Run 返回错误 - 它有Cloud Run Invoker

除了授予权限之外,我需要做些什么才能让 API Gateway 调用云运行吗?Cloud Run Invoker

4

1 回答 1

1

不建议添加 32555940559.apps.googleusercontent.com,因为这是默认设置。理想情况下,每个服务的受众都应该是唯一的,这就是我们通常为此使用服务自己的 URL 的原因。这可以防止令牌被重用,例如被恶意或不安全的服务器重用,以向期望不同受众的其他服务进行身份验证。

您可以在创建身份令牌时指定要使用的受众。例如: gcloud auth print-identity-token --audiences "https://service-acldswax.fx.gateway.dev"

您可以指定相同的受众x-google-audiences来完成这项工作。或者,默认情况下将接受以“https://”为前缀的服务名称。这可以在 API 规范文件中指定为“主机”,通常类似于“api.example.com”。

请注意,任何人都可以生成有效的身份令牌,网关将接受该身份令牌。网关正在执行 /authentication/,但不执行 /authorization/。您可以在应用程序中进行授权,或者对于私有 API,您可能希望使用不同的 oauth2 客户端。

正确设置后,您应该能够连接到 API 网关,但您可能希望锁定 Cloud Run 服务,以防止网关被绕过。正如您所提到的,执行此操作所需的权限包含在“Cloud Run Invoker”角色中,这需要授予网关在 Cloud Run 服务上的服务帐户之一,其包含资源(例如项目、文件夹、组织)。

我建议运行以下命令再次确认/检查设置:

  • 验证网关中的 URL 和 API 配置:gcloud api-gateway gateways describe $GATEWAY --location $REGION
  • 验证网关配置服务帐户和后端 URL(在 base64 编码的 document.contents 中):gcloud api-gateway api-configs describe --api $API $API_CONFIG --view FULL
  • 验证 Cloud Run 服务的权限: gcloud run services --region $REGION get-iam-policy $SERVICE
于 2021-11-09T05:51:11.663 回答