aws-cloudfront: easily support Origin Access Identity for S3 buckets
See original GitHub issueCurrently it doesn’t seem possible to do this without creating a CloudFrontOriginAccessIdentityResource and then creating a ‘Canonical User’ policy fragment.
Here’s the Java version:
Bucket bucket = new Bucket(this, "Bucket", BucketProps.builder()
.build());
CloudFrontOriginAccessIdentityResource identityResource = new CloudFrontOriginAccessIdentityResource(this, "OAI", CloudFrontOriginAccessIdentityResourceProps.builder()
.withCloudFrontOriginAccessIdentityConfig(new CloudFrontOriginAccessIdentityResource.CloudFrontOriginAccessIdentityConfigProperty.Builder()
.withComment("A comment")
.build()
)
.build());
CloudFrontWebDistribution webDistribution = new CloudFrontWebDistribution(this, "CloudFront", CloudFrontWebDistributionProps.builder()
.withViewerProtocolPolicy(ViewerProtocolPolicy.RedirectToHTTPS)
.withPriceClass(PriceClass.PriceClass100)
.withHttpVersion(HttpVersion.HTTP2)
.withDefaultRootObject("")
.withOriginConfigs(Collections.singletonList(
SourceConfiguration.builder()
.withBehaviors(Collections.singletonList(
Behavior.builder()
.withAllowedMethods(CloudFrontAllowedMethods.ALL)
.withDefaultTtlSeconds(60)
.withIsDefaultBehavior(true)
.withForwardedValues(DistributionResource.ForwardedValuesProperty.builder()
.withCookies(DistributionResource.CookiesProperty.builder()
.withWhitelistedNames(Arrays.asList(
"csrftoken",
"sessionid",
"messages"
))
.withForward("whitelist")
.build())
.withQueryString(true)
.build())
.build()
))
.withS3OriginSource(S3OriginConfig.builder()
.withS3BucketSource(bucket)
.withOriginAccessIdentity(identityResource)
.build())
.withOriginHeaders(new HashMap<String, String>() {{
put("X-CloudFront-Forwarded-Proto", "https");
}})
.build()
))
.build());
class CanonicalUserPrincipal extends AccountPrincipal {
private String canonicalUserId;
private CanonicalUserPrincipal(String canonicalUserId) {
this.canonicalUserId = canonicalUserId;
}
@Override
public PrincipalPolicyFragment policyFragment() {
return new PrincipalPolicyFragment(new HashMap<String,String>() {{
put("CanonicalUser", canonicalUserId);
}});
}
}
PolicyDocument document = new PolicyDocument();
document.addStatement(new PolicyStatement()
.addPrincipal(new CanonicalUserPrincipal(identityResource.getCloudFrontOriginAccessIdentityS3CanonicalUserId()))
.addAction("s3:GetObject")
.addResource("arn:aws:s3:::" + bucket.getBucketName() + "/*")
);
new BucketPolicyResource(this, "BucketPolicy", BucketPolicyResourceProps.builder()
.withBucket(bucket.getBucketName())
.withPolicyDocument(document)
.build());
Issue Analytics
- State:
- Created 5 years ago
- Reactions:7
- Comments:11 (9 by maintainers)
Top Results From Across the Web
Restricting access to an Amazon S3 origin - Amazon CloudFront
If your origin is an Amazon S3 bucket configured as a website endpoint, you must set it up with CloudFront as a custom...
Read more >Cloudfront Origin Access Identity (OAI): How to use it? - StormIT
1. Log in to the CloudFront Console. · 2. Click on “Create Distribution”. · 3. Select S3 bucket as origin domain, choose “Yes...
Read more >Securing S3 with Origin Access Identity (OAI) via CloudFront
In my introductory AWS CloudFront article, it was explained how we can secure native and custom origins via CloudFront. Out of those methods, ......
Read more >How Origin Access Identity works - Advanced Web Machinery
The Origin Access Identity (OAI) is the primary way to make CloudFront access private content stored in S3. Without it, CloudFront is like...
Read more >Creating an S3 bucket policy that allows access to Cloudfront ...
Details here: Using an Origin Access Identity to Restrict Access to Your Amazon S3 Content - Amazon CloudFront.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
FYI, I got this working by changing the policy statement I was creating to this:
To match what the CDK was doing in other parts I added the bucketArn and the bucketArn with /*. I also changed the
addArnPrincipal
toaddCanonicalUserPrincipal
. This now properly creates a CloudFront distribution that has access to the bucket.I created a class to make this easier called
StaticWebsiteStack
that lets you pass in some variables and it does all the magic needed to create the bucket, the Cloud Front distro and the bucket policy for a static website. It also supports versioning. The code is here with an example website (look in the /aws directory): https://github.com/dsandor/cdk-static-websiteAgreed. Passing the S3 bucket should do all this work.