【问题标题】:Error 401 calling static Html hosted on Cloud Storage from Cloud Endpoint从 Cloud Endpoint 调用托管在 Cloud Storage 上的静态 Html 时出现错误 401
【发布时间】:2020-03-24 04:23:05
【问题描述】:

调用托管在 Cloud Storage 存储分区上的静态 HTML 页面时,我收到 401 错误。

Cloud Storage 存储分区配置为公共。

调用是从我的 Cloud Endpoint 完成的,如下所示:

/my-web-page:
      get:
        summary: call my web page
        operationId: my-web-page
        x-google-allow: all
        x-google-backend:
          address: https://storage.googleapis.com/MY-PROJECT/[MY-BUCKET]/[MY-OBJECT]
        responses:
          '200':
            description: A successful response
            schema:
              type: string 

云运行日志:

XX.XXX.XXX.XXX - "GET https://[MY-CLOUD-ENDPOINT-SERVICE].a.run.app/my-web-page" **401** 804 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763"
Expand all | Collapse all{
 httpRequest: {
  latency: "2.377394394s"   
  protocol: "HTTP/1.1"   
  remoteIp: "XXXXX"   
  requestMethod: "GET"   
  requestSize: "693"   
  requestUrl: "https://[MY-CLOUD-ENDPOINT-SERVICE].a.run.app/storage"   
  responseSize: "804"   
  serverIp: "XXXXXXX"   
  status: 401   
  userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763"   
 }
 insertId: "5ddef2f900077a8473972018"  
 labels: {…}  
 logName: "projects/[MY-GCP-PROJECT]/logs/run.googleapis.com%2Frequests"  
 receiveTimestamp: "2019-11-27T22:04:41.498296805Z"  
 resource: {
  labels: {
   configuration_name: "XXXXX"    
   location: "us-central1"    
   project_id: "XXXXX"    
   revision_name: "XXXX"    
   service_name: "XXXX"    
  }
  type: "cloud_run_revision"   
 }
 severity: "WARNING"  
 timestamp: "2019-11-27T22:04:41.490116Z"  
 trace: "projects/XXXXXX/traces/aed367cb2b64bf00c215f8b19dff446b"  
}

有什么想法吗?

【问题讨论】:

  • 您是否在 Cloud Run 中部署了带有标志 --allow-unauthenticated 的 ESP?

标签: google-cloud-platform google-cloud-storage google-cloud-endpoints google-cloud-run terraform-provider-gcp


【解决方案1】:

这里发生的情况是x-google-backend 正在尝试通过创建服务帐户身份令牌来对存储进行身份验证。

另一方面,Storage 只接受 OAuth 或根本不接受授权。它从 ESP 获得的令牌被简单地忽略并视为垃圾。

您甚至可以使用 curl -H 'Authorization: Bearer garbage' https://storage.googleapis.com/bucket/buildings.jpg 并仍然得到完全相同的错误。

暂时无法关闭此功能的授权,因此无法使用googleapis。

另一种方法是修改 ESP 映像,以便通过添加文件 /var/lib/nginx/extra/hello.conf 并修改 gcloud_build_image 以包含此配置来将自定义位置添加到 nginx 配置。

这样它将完全跳过端点,因此可以从 openapi-run.yaml 中删除。您可以检查两个文件here

如果这能解决您的问题,请告诉我。

【讨论】:

  • 嗨@Waelmas,当我尝试将解决方案部署到新的 GCP 项目时,出现此错误:
  • INFO - nginx: [warn] 只有当主进程以超级用户权限运行时,“user”指令才有意义,在 /home/nginx/endpoints/nginx.conf:29 中被忽略 br> INFO - 2019/12/10 16:44:13 [warn] 1#1:“user”指令仅在主进程以超级用户权限运行时才有意义,在 /home/nginx/endpoints/nginx 中被忽略.conf:29 INFO - nginx:[emerg] /var/lib/nginx/extra/hello.conf:8 中的 URL 前缀无效 INFO - 2019/12/10 16:44:13 [ emerg] 1#1:/var/lib/nginx/extra/hello.conf:8 中的 URL 前缀无效 错误 - 容器调用 exit(1)。
  • 由于这个 nginx 配置问题,容器似乎没有启动
  • 抱歉,忘记了...我在 hello.conf 中引入了导致问题的类型
【解决方案2】:

当您使用端点向 Cloud Storage API 发出请求时,我认为您应该改用以下地址:

https://storage.googleapis.com/storage/v1/[PATH_TO_RESOURCE]

由于端点很可能向 API 发出 JSON 请求,因此文档中的 link 将对您有用。

编辑:

我终于设法使用以下端点配置使其与您的相同设置一起工作:

/hello:
  get:
    summary: hello
    operationId: GetImage
    x-google-backend:
      #address: https://storage.googleapis.com/[MY-BUCKET]/[MY-OBJECT]
      address: https://storage.cloud.google.com/[MY-BUCKET]/[MY-OBJECT]
    responses:
      '200':
        description: hello
        schema:
          type: object

这个设置的问题是文件将从storage.cloud.google.com 提供,因此用户将被重定向到apidata.googleusercontent.com。我相信它不适用于 googleapis.com,因为 Endpoints 并不意味着调用其他 API,然后调用 storage.google.com URL 将起作用。

【讨论】:

  • 即使在这种情况下,我也会收到:code { "error": { "code": 401, "message": "Invalid Credentials", "errors": [ { "message" :“无效凭据”、“域”:“全局”、“原因”:“authError”、“locationType”:“标题”、“位置”:“授权”} ] } } ```
  • 那么现在我建议您尝试缩小问题范围,看看它究竟是在哪里生成的,因为您正在使用 GCS、GCRun 和 Endpoints。到目前为止,我一直在尝试在我这边复制它,但没有运气。但是,从公共 GCS 存储桶开始,以下将返回错误:curl https://storage.googleapis.com/[MY-PROJECT]/[MY-BUCKET]/[OBJECT] 但是,没有该项目,它对我有用:curl https://storage.googleapis.com/[MY-BUCKET]/[OBJECT] 你也可以试试吗?在这种情况下,我们可能会忽略问题来自 GCS。
  • @FELIPECEMBRANELLI 我已经用一个对我有用的解决方案更新了我的答案,让我知道这是否也适合你。
  • 感谢您的回归。但它仍然无法正常工作......问题是当我试图从未经谷歌认证的网络浏览器会话中访问它时。你测试过吗?为我弹出 Google 身份验证页面。
  • 只是为了补充,请求被重定向到--> accounts.google.com/ServiceLogin/…
【解决方案3】:

这是 ESP 中的一个错误,它总是将 ID 令牌发送到后端。由于您的 GCS 存储桶是公开的,因此如果存储 API 没有任何 JWT 令牌,它应该可以工作。但如果它有任何 JWT 令牌,则调用失败。

我们正在努力修复。但由于假期发布被冻结,修复将在明年推出。

有一个技巧可以解决它。

1) 通过以下方式部署您的 OpenAPI 规范:

gcloud endpoints deploy you_open_api.json

2) 从 Google 服务管理服务下载其编译后的配置文件

gcloud endpoints configs describe ... > tmp.xml

3) 删除 tmp.xml 中“后端”部分中带有“jwt_audience”的行 想法是:如果 jwt_audience 字段为空,ESP 将不会生成 ID 令牌。但是在 x-google-backend OpenApi 规范中,即使您没有指定 jwt_audience,编译器也会自动将“address”字段分配给“jwt_audience”字段。

4) 通过以下方式将 tmp.xml 重新部署到 google 服务管理:

gcloud endpoints deploy tmp.xml

通过此更改,ESP 在调用存储 API 时将不会生成 ID 令牌。

【讨论】:

    猜你喜欢
    • 2020-08-11
    • 1970-01-01
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-28
    相关资源
    最近更新 更多