HTTP no-cache access to S3 versioned objects

0

I'm surprised I haven't seen this issue online.

Currently I have an S3 bucket that is served through Cloudfront on a custom domain. e.g. An S3 bucket object is retrievable publicly via https://cdn.mywebsite.com/picture.jpeg.

The cloudfront distribution connects with the origin (S3) through an OAC, and the policy was applied to the bucket correctly.

I am able to retrieve all objects today, however there is some invisible caching and I'm unsure how to get around it.

For example, I can reach and retrieve https://cdn.mywebsite.com/picture.jpeg without issues. Then, when I go to retrieve https://cdn.mywebsite.com/picture.jpeg?versionId=...., I get the same response as the prior call. It's cached.

How can I retrieve https://cdn.mywebsite.com/picture.jpeg?versionId=.... without caching?

Here's what I've tried:

  • Under my origin behavior, I have used the CachingDisabled policy under "Cache key and origin requests". This does indeed disable caching, but that policy doesn't forward query string arguments, so picture.jpeg and picture.jpeg?versionId=... are retrieved equivalently.
  • I have tried creating an identical cache policy as CachingDisabled, with Query strings - All set for the cache key settings. As a result, I get a 403 error.

My interpretation is that when a request is sent via cdn.myexample.com/picture.jpeg?versionId=..., that version query string is stripped off before going to the S3 bucket. Hence, it doesn't cache picture.jpeg, but it's not retrieving the right image anymore.

1回答
1
承認された回答

Hey all, I fixed it. Since this had me pulling my hair out, here was my solution:

  • On the Cloudfront distribution, Edit the Behavior for the S3 Cloudfront bucket.
  • Find Cache key and origin requests and edit this so Headers includes the Origin, and set Query strings to All.

Finally, this is an important step. On the S3 bucket, you must give access to the Cloudfront distribution to get version tagging. I haven't narrowed down exactly which action solved it for me, but here's what worked:

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersionTagging",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::.... my bucket",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::..... my distribution"
                }
            }
        },
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketVersions"
            ],
            "Resource": "arn:aws:s3:::.... my bucket",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::..... my distribution"
                }
            }
        }
    ]
}
回答済み 1ヶ月前
profile picture
エキスパート
レビュー済み 1ヶ月前
profile picture
エキスパート
レビュー済み 1ヶ月前

ログインしていません。 ログイン 回答を投稿する。

優れた回答とは、質問に明確に答え、建設的なフィードバックを提供し、質問者の専門分野におけるスキルの向上を促すものです。

質問に答えるためのガイドライン

関連するコンテンツ