Serving Personal Content from CloudFront with Signed Cookies
Cloudfront supports signed cookies to serve personal content, but I can't find examples on how to do this.
I found examples of how to sign URLs with Java AWS API but not Cookies, can someone please share their experience with this and this is the best way to secure multiple media forms to be served with CloudFront.
Our site has images and videos that are uploaded by the user, which can then be viewed in search results on our site. I want these images to be served only by our site and not copied for later use.
source to share
We were able to inject signed cookies with custom policies using this library
You need three cookies generated by your app as described here http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-custom-policy.html
Please read this carefully. Especially how to create a policy.
Three cookies:
- CloudFront Policies
- CloudFront-Signature
- CloudFront-Key-Pair-Id
First create a policy
Date expirationTime = (new LocalDate()).plusYears(1).toDate();
String customPolicy = CloudFrontService.buildPolicyForSignedUrl(basePath, expirationTime, null, null);
//and assign it to a cookie
Cookie signedCookiePolicy = new Cookie("CloudFront-Policy", ServiceUtils.toBase64(customPolicy.getBytes()));
signedCookiePolicy.setMaxAge(365 * 24 * 60 * 60);
signedCookiePolicy.setPath("/");
response.addCookie(signedCookiePolicy);
Signing is the tricky part, but all tools are available as soon as you use this thing jets3t
byte[] signatureBytes = EncryptionUtil.signWithRsaSha1(getDerPrivateKey(), customPolicy.getBytes("UTF-8"));
String signature = ServiceUtils.toBase64(signatureBytes).replace('+', '-').replace('=', '_').replace('/', '~');
Cookie signedCookieSignagture = new Cookie("CloudFront-Signature",cdnSignService.signBaseUrl(basePath, expirationTime));
signedCookieSignagture.setMaxAge(365 * 24 * 60 * 60);
signedCookieSignagture.setPath("/");
response.addCookie(signedCookieSignagture);
The third cookie only contains the key identifier for your AWS account.
Cookie signedCookieKeyPairId = new Cookie("CloudFront-Key-Pair-Id","YOUR_AWS_CF_KEY_ID");
signedCookieKeyPairId.setMaxAge(365 * 24 * 60 * 60);
signedCookieKeyPairId.setPath("/");
response.addCookie(signedCookieKeyPairId);
In the section above, you will learn the concepts of using the correct libraries to create signed cookies. Its not executable or executable by itself.
Be so kind as his first contribution to the overflow.
source to share
AWS JAVA SDK Release 1.10.73 introduced the CloudFrontCookieSigner class for signed cookies with custom policies. Using this class and methods, we can create cookies.
- CloudFront-Signature
- CloudFront Policies
-
CloudFront-Key-Pair-Id
Please note that Java only supports DER format SSL certificates, so you will need to convert the PEM format file to DER format.
You can use openssl for this:
Command to create .der file from .pem
openssl pkcs8 -topk8 -nocrypt -in origin.pem -inform PEM -out new.der -outform DER
Link: - http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CFPrivateDistJavaDevelopment.html
String privateKeyFilecdr = "/home/ec2-user/cookie.der";
String distributionDomain = "xxxxxxxx.cloudfront.net";
String s3ObjectKey = "signed-cookie.png";
String distributionid = "X4X4X4Y5Y5"; //Cloud Front Distribution id
String KeyFileId = "MPSIKFGHLMNSTOP" //AWS PEM KEY FILE ID
Date expiresOn = DateUtils.parseISO8601Date("2012-11-14T22:20:00.000Z");
String policyResourcePath = "https://" + distributionDomain + "/" + s3ObjectKey;
File privateKeyFile = new File(privateKeyFilecdr);
CookiesForCannedPolicy cookies = null;
try {
cookies = CloudFrontCookieSigner.getCookiesForCannedPolicy(policyResourcePath, KeyFileId, privateKeyFile, expiresOn);
// @SuppressWarnings({ "resource", "deprecation" })
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(SignerUtils.generateResourcePath(Protocol.https, distributionDomain,
s3ObjectKey));
httpGet.addHeader("Cookie", cookies.getExpires().getKey() + "=" +
cookies.getExpires().getValue());
httpGet.addHeader("Cookie", cookies.getSignature().getKey() + "=" +
cookies.getSignature().getValue());
httpGet.addHeader("Cookie", cookies.getKeyPairId().getKey() + "=" +
cookies.getKeyPairId().getValue());
HttpResponse responsevalues = client.execute(httpGet);
// System.out.println(responsevalues);
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
source to share