带有 API 密钥的 GCP API 网关失败,并显示 403 错误,指出 ... .cloud.goog 未为该项目启用

问题描述 投票:0回答:2

首先,让我向您展示一些我的 gcloud 设置。当我运行

gcloud config list
时,这是我的输出:

[core]
account = <SERVICE ACCOUNT NAME>@<PROJECT NAME>.iam.gserviceaccount.com
disable_usage_reporting = True
project = <PROJECT NAME>

Your active configuration is: [default]

当我运行

gcloud services list
时,这是我的输出:

apigateway.googleapis.com            API Gateway API
artifactregistry.googleapis.com      Artifact Registry API
bigquery.googleapis.com              BigQuery API
bigquerymigration.googleapis.com     BigQuery Migration API
bigquerystorage.googleapis.com       BigQuery Storage API
cloudapis.googleapis.com             Google Cloud APIs
cloudbuild.googleapis.com            Cloud Build API
clouddebugger.googleapis.com         Cloud Debugger API
cloudfunctions.googleapis.com        Cloud Functions API
cloudresourcemanager.googleapis.com  Cloud Resource Manager API
cloudtrace.googleapis.com            Cloud Trace API
containerregistry.googleapis.com     Container Registry API
datastore.googleapis.com             Cloud Datastore API
eventarc.googleapis.com              Eventarc API
iam.googleapis.com                   Identity and Access Management (IAM) API
iamcredentials.googleapis.com        IAM Service Account Credentials API
logging.googleapis.com               Cloud Logging API
monitoring.googleapis.com            Cloud Monitoring API
oslogin.googleapis.com               Cloud OS Login API
pubsub.googleapis.com                Cloud Pub/Sub API
run.googleapis.com                   Cloud Run Admin API
secretmanager.googleapis.com         Secret Manager API
servicecontrol.googleapis.com        Service Control API
servicemanagement.googleapis.com     Service Management API
serviceusage.googleapis.com          Service Usage API
source.googleapis.com                Legacy Cloud Source Repositories API
sql-component.googleapis.com         Cloud SQL
storage-api.googleapis.com           Google Cloud Storage JSON API
storage-component.googleapis.com     Cloud Storage
storage.googleapis.com               Cloud Storage API
sts.googleapis.com                   Security Token Service API

我有一个带有以下配置文件的 API 网关:

swagger: '2.0'
info:
  title: <API TITLE>
  description: API Gateway First for Sphrn Testing
  version: 1.0.0
securityDefinitions:
  api_key_header:
    type: apiKey
    name: x-api-key
    in: header
schemes:
  - https
produces:
  - application/json
paths:
  /entrypoint1:
    post:
      summary: Simple echo service
      operationId: <OPERATION ID HERE>
      x-google-backend:
        address: https://<CLOUD FUNCTION NAME>-<STRING I DON'T RECOGNIZE>-uc.a.run.app
      security:
        - api_key_header: []
      responses:
        '200':
          description: OK

我使用以下脚本从命令行调用 api:

curl --location --request POST 'https://<API CALLABLE ENDPOINT>.uc.gateway.dev/endpoint1' \
--header 'X-goog-api-key: <MY API KEY HERE>' \
--header 'Content-Type: application/json; charset=utf-8' \
--data-raw '{
    "name": "Test1"
}'

但在我的终端中失败了:

{"code":403,"message":"PERMISSION_DENIED:API <SERVICE ACCOUNT NAME>-<STRING I DON'T RECOGNIZE>.apigateway.<PROJECT NAME>.cloud.goog is not enabled for the project."}

我的 API 密钥如下所示:

我进入了 API 网关端点的日志资源管理器,这是来自 403 失败的 curl 命令的更详细的日志(当然,为了识别信息而进行了清理):

{
    "httpRequest": {
        "latency": "0.040s",
        "protocol": "http",
        "remoteIp": "<MY IP ADDRESS>",
        "requestMethod": "POST",
        "requestSize": "1053",
        "requestUrl": "/endpoint1",
        "responseSize": "346",
        "status": 403
    },
    "insertId": "<LONG GUID LOOKING STRING>@a1",
    "jsonPayload": {
        "api_key": "<MY API KEY>",
        "api_key_state": "NOT ENABLED",
        "api_method": "1.<API ID>_<STRING I DON'T RECOGNIZE>_apigateway_<PROJECT NAME>_cloud_goog.<OPERATIONID FROM CONFIG YAML>",
        "api_name": "1.<API ID>_<STRING I DON'T RECOGNIZE>_apigateway_<PROJECT NAME>_cloud_goog",
        "api_version": "1.0.0",
        "error_cause": "API <API ID>_<STRING I DON'T RECOGNIZE>.apigateway.<PROJECT NAME>.cloud.goog is not enabled for the project.",
        "http_status_code": 403,
        "location": "us-central1",
        "log_message": "1.<API ID>_<STRING 1 I DON'T RECOGNIZE>_apigateway_<PROJECT NAME>_cloud_goog.<OPERATIONID FROM CONFIG YAML> is called",
        "producer_project_id": "<PROJECT NAME>",
        "response_code_detail": "service_control_check_error{SERVICE_NOT_ACTIVATED}",
        "service_agent": "ESPv2/2.40.0",
        "service_config_id": "<CONFIGURATION ID>",
        "timestamp": "<TIMESTAMP HERE AS DECIMAL>"
    },
    "logName": "projects/<PROJECT NAME>/logs/<API ID>_<STRING I DON'T RECOGNIZE>.apigateway.<PROJECT NAME>.cloud.goog%2Fendpoints_log",
    "receiveTimestamp": "<TIMESTAMP HERE AS STRING>",
    "resource": {
        "labels": {
            "location": "us-central1",
            "method": "1.<API ID>-<STRING I DON'T RECOGNIZE>_apigateway_<PROJECT NAME>_cloud_goog.<OPERATIONID FROM CONFIG YAML>",
            "project_id": "<PROJECT NAME>",
            "service": "<API ID>-<STRING I DON'T RECOGNIZE>.apigateway.<PROJECT NAME>.cloud.goog",
            "version": "1.0.0"
        },
        "type": "api"
    },
    "severity": "ERROR",
    "timestamp": "<TIMESTAMP HERE AS STRING>"
}

那么我怎样才能让这个卷曲成功......?我假设这是一个权限问题,但是我的服务帐户没有什么权限?

当我跑步时:

gcloud projects get-iam-policy <PROJECT ID> \
--flatten="bindings[].members" \
--format='table(bindings.role)' \
--filter="bindings.members:<SERVICE ACCOUNT NAME>@<PROJECT NAME>.iam.gserviceaccount.com"

我得到这个输出:

ROLE
roles/cloudfunctions.serviceAgent
roles/serviceusage.serviceUsageViewer
api google-cloud-platform google-api api-gateway
2个回答
2
投票

我必须使用我创建 GCP 项目的实际“主”Gmail 帐户来启用该服务,并通过

<SERVICE ACCOUNT NAME>-....apigateway.<PROJECT NAME>.cloud.goog
命令启用该服务
gcloud
。然后我又遇到了 1 个问题,我没有启用 API 密钥限制菜单中 openapi 配置 yaml 文件中列出的
operationId

我假设阅读本文的任何人都已经通过

gcloud auth login
使用他们的服务帐户登录,并使用
gcloud auth activate-service-account <SERVICE ACCOUNT NAME>@<PROJECT NAME>.iam.gserviceaccount.com --key-file=/path/to/keyfile.json

激活了他们的相关服务帐户

启用服务修复
我使用

gcloud config set account <MASTER GCLOUD ACCOUNT NAME>@gmail.com
将我的 gcloud 帐户切换到我的“主”帐户,然后:

gcloud services enable <SERVICE ACCOUNT NAME>-....apigateway.<PROJECT NAME>.cloud.goog \
--project=<PROJECT ID (THE NUMBER NOT THE TEXT NAME>

这使得使用标头中的 API 密钥调用 API 会出现新错误

{"message":"PERMISSION_DENIED: The API targeted by this request is invalid for the given API key.","code":403}

operationId API 限制菜单修复
我必须在 API 密钥限制菜单中启用 openapi 配置 yaml 文件中列出的

operationId
。之后,它出现在 API 密钥凭证页面的“选定的 API”部分中:

进行此更改后,我的卷曲请求:

curl --location --request POST 'https://<API CALLABLE ENDPOINT>.uc.gateway.dev/endpoint1' \
--header 'X-goog-api-key: <MY API KEY HERE>' \
--header 'Content-Type: application/json; charset=utf-8' \
--data-raw '{
    "name": "Test1"
}'

工作完美!


0
投票

除了Christian的回答之外,它的地形解决方案是:

模块/api_gateway/main.tf

resource "google_api_gateway_api" "api_gw" {
    provider = google-beta
    api_id = var.api_id
}

模块/api_gateway/outputs.tf

output "api-managed-service" {
    value = google_api_gateway_api.api_gw.managed_service
}

模块/api_key/main.tf

resource "google_apikeys_key" "api_key" {
    name         = var.api_key_name
    display_name = var.api_key_display_name

    restrictions {
        api_targets {
            service = var.api_target_service
            methods = ["GET*"]
            }
        api_targets {
            service = "apigateway.googleapis.com" 
            }
        api_targets {
            service = "cloudfunctions.googleapis.com" 
            }
 }
}

主.tf

module "api-key" {
    source = "./modules/api_key"
    api_key_name = var.api_key_name
    api_key_display_name = var.api_key_display_name
    api_target_service = module.api-gateway.api-managed-service
}
© www.soinside.com 2019 - 2024. All rights reserved.