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"
                }
            }
        }
    ]
}
답변함 한 달 전
profile picture
전문가
검토됨 한 달 전
profile picture
전문가
검토됨 한 달 전

로그인하지 않았습니다. 로그인해야 답변을 게시할 수 있습니다.

좋은 답변은 질문에 명확하게 답하고 건설적인 피드백을 제공하며 질문자의 전문적인 성장을 장려합니다.

질문 답변하기에 대한 가이드라인

관련 콘텐츠