从 Cloud Endpoint 调用托管在 Cloud Storage 上的静态 Html 时出现错误 401
Error 401 calling static Html hosted on Cloud Storage from Cloud Endpoint
-
google-cloud-storage
-
google-cloud-endpoints
-
google-cloud-platform
-
terraform-provider-gcp
-
google-cloud-run
我在调用 Cloud Storage 存储桶上托管的静态 HTML 页面时收到 401 错误。
Cloud Storage 存储桶配置为 Public。
调用是从我的 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"
}
有什么想法吗?
当您使用端点向云存储 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,因为端点并不意味着调用其他 API,然后调用 storage.google.com
URL 将起作用。
这里发生的事情是 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.
如果这能解决您的问题,请告诉我。
这是 ESP 中的一个错误,它总是向后端发送 ID 令牌。由于您的 GCS 存储桶是 public,如果它没有任何 JWT 令牌,对存储 API 的请求应该有效。但是如果它有任何 JWT 令牌,调用就会失败。
我们正在努力修复。但由于假日发布冻结,该修复程序将于明年推出。
有一个 hack 可以解决它。
1) 通过以下方式部署您的 OpenAPI 规范:
gcloud endpoints deploy you_open_api.json
2) 从Google 服务管理服务
下载编译后的配置文件
gcloud endpoints configs describe ... > tmp.xml
3) 删除 tmp.xml 中 "Backend" 部分带有 "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 将不会在调用存储时生成 ID 令牌 API。
google-cloud-storage
google-cloud-endpoints
google-cloud-platform
terraform-provider-gcp
google-cloud-run
我在调用 Cloud Storage 存储桶上托管的静态 HTML 页面时收到 401 错误。
Cloud Storage 存储桶配置为 Public。
调用是从我的 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"
}
有什么想法吗?
当您使用端点向云存储 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,因为端点并不意味着调用其他 API,然后调用 storage.google.com
URL 将起作用。
这里发生的事情是 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.
如果这能解决您的问题,请告诉我。
这是 ESP 中的一个错误,它总是向后端发送 ID 令牌。由于您的 GCS 存储桶是 public,如果它没有任何 JWT 令牌,对存储 API 的请求应该有效。但是如果它有任何 JWT 令牌,调用就会失败。
我们正在努力修复。但由于假日发布冻结,该修复程序将于明年推出。
有一个 hack 可以解决它。
1) 通过以下方式部署您的 OpenAPI 规范:
gcloud endpoints deploy you_open_api.json
2) 从Google 服务管理服务
下载编译后的配置文件gcloud endpoints configs describe ... > tmp.xml
3) 删除 tmp.xml 中 "Backend" 部分带有 "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 将不会在调用存储时生成 ID 令牌 API。