1

几个月来,我一直在使用 Google Cloud CDN 缓存 GCS 存储桶中的内容。直到昨天(2019/09/19),我注意到我无法访问名称中包含空格的对象。通常,我encodeURIComponent在签署整个 URL 之前申请对象的名称,直到昨天它一直运行良好。

这是我迄今为止尝试过的gcloud实用程序:

  1. 对 URL 进行签名,而不对文件名进行 URL 编码:

    $ gcloud compute sign-url --key-name my-key --key-file my-key --expires-in 15m "https://cdn.example.com/file-with-white space.txt"

    然后我访问了带有和不带有%20. 结果是403,如图所示。

  2. 使用 URL 编码文件的名称对 URL 进行签名(这是我几个月来一直在做的事情,而且效果很好):

    $ gcloud compute sign-url --key-name my-key --key-file my-key --expires-in 15m "https://cdn.example.com/file-with-white%20space.txt"

    结果也是 403 但有不同的消息

匿名调用者没有 storage.objects.get 访问存储桶/文件名的权限

我还尝试使用此链接中的 Go 代码。结果是一样的。

请注意,名称中没有空格的文件仍然可以通过 CDN 成功访问。


更新

  1. 澄清一下,我认为 CDN 的行为已经改变。
  2. 我已授予 CDN 访问 GCS 存储桶的权限。这就是为什么 CDN 之前可以正常工作的原因。我实际上已经跑gsutil iam ch serviceAccount:service-PROJECT_NUM@cloud-cdn-fill.iam.gserviceaccount.com:objectViewer gs://[BUCKET]了两次来确保这一点。
  3. 我曾尝试gsutil直接使用而不使用 CDN 对 GCS URL 进行签名,并且签名的 URL 有效。

更新 2

我已经尝试了该--validate选项。这就是我得到的:

$ gcloud compute sign-url --key-name cdn-signing-key \
  --key-file cdn-signing-key --expires-in 15m \
  --validate "https://cdn.domain.com/file%20with%20space"

signedUrl: https://cdn.domain.com/file%20with%20space?Expires=1569075302&KeyName=cdn-signing-key&Signature=e3SANudKHIT5txHWVlO1oijItXw=
validationResponseCode: 200

然而,通过浏览器访问“signedUrl”时,我仍然收到 403。结果是一个带有<Code>AccessDenied</Code>.

4

2 回答 2

0

我无法复制这个。

可以对 GCS 存储桶中带有空格的(URL 编码的)文件名进行签名和验证:

➜  gcloud compute sign-url --key-name "backend-key" \
  --key-file backend.key --expires-in 7d \
  --validate "https://cloud-cdn.questionable.services/file%20with%20spaces.txt"

signedUrl: https://cloud-cdn.questionable.services/file%20with%20spaces.txt?Expires=1569639576&KeyName=backend-key&Signature=pTsgDpBOpBcqHDNeTWFfFcTC2Ws=
validationResponseCode: 200

如果没有 URL 编码,验证和签名将失败(如预期的那样),因为 gcloud 不会自动对 URL 进行百分比编码:

➜  gcloud compute sign-url --key-name "backend-key" \
  --key-file backend.key --expires-in 7d \
  --validate "https://cloud-cdn.questionable.services/file with spaces.txt"

signedUrl: https://cloud-cdn.questionable.services/file with spaces.txt?Expires=1569639586&KeyName=backend-key&Signature=AiJEBO6sHGgJh8EshLAH2IXlxe0=
validationResponseCode: 400

Cloud CDN 端的签名算法没有任何变化,sign-urlgcloud SDK 中的命令也没有变化。过去我们没有对输入 URL 进行隐式 URL 编码。

于 2019-09-21T03:11:56.860 回答
0

今天早上,我再次尝试访问带有空格的文件的新签名 URL。我注意到一些有趣的事情。

  • 有时,CDN 工作并返回 200 以及文件的内容。
  • 有时,CDN 会从后端服务(在本例中为 GCS 存储桶)获得 301 作为响应,然后将我重定向到存储桶 URL,该 URL 又返回 403 以及 XML 页面。
  • 所以我尝试将存储桶的权限更改为Public. 如果 CDN 有效,我会像以前一样收到 200。如果 CDN 将我重定向到存储桶,现在我将收到 200 以及文件。

所以我要结束这个问题,因为我认为它与文件名无关了。似乎 CDN 没有为我缓存内容,而是尝试将原始文件定向到存储桶中。我不确定这是否是 CDN 的正常行为,但我会对此进行更多研究。

于 2019-09-23T07:35:03.153 回答