使用签名Cookie从CloudFront提供私人内容

时间:2015-04-27 00:26:12

标签: amazon-web-services amazon-cloudfront

Cloudfront支持使用已签名的Cookie来提供私人内容,但我找不到任何有关如何执行此操作的示例。

我找到了有关如何使用Java AWS API签署URL而不是Cookie的示例,有人可以分享他们这样做的经验,这是确保从CloudFront提供多种媒体形式的最佳方式。

我们的网站上有用户上传的图片和视频,然后可以通过我们网站上的搜索进行查看,我想确保这些图片只能由我们的网站提供,不能复制供以后使用。< / p>

2 个答案:

答案 0 :(得分:7)

我们能够使用自定义政策引入已签名的Cookie 这个图书馆

http://www.jets3t.org/

您需要根据此处所述的应用创建三个Cookie http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-custom-policy.html

请仔细阅读。特别是关于如何制定政策的部分。

这三个饼干是:

  1. CloudFront的-政策
  2. CloudFront的签名
  3. CloudFront的-密钥对-ID
  4. 首先制定政策

    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);
    

    签名是棘手的部分,但是一旦你使用这个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);
    

    第三个Cookie仅包含您的AWS账户的密钥ID。

    Cookie signedCookieKeyPairId = new Cookie("CloudFront-Key-Pair-Id","YOUR_AWS_CF_KEY_ID");
    signedCookieKeyPairId.setMaxAge(365 * 24 * 60 * 60);
    signedCookieKeyPairId.setPath("/");
    response.addCookie(signedCookieKeyPairId);
    

    以上仅介绍使用正确的libs创建签名cookie的概念。它本身不可执行或可运行。

    很好,这是我的第一次溢出贡献......

答案 1 :(得分:1)

在AWS JAVA SDK版本1.10.73中,为带有自定义策略的签名Cookie引入了CloudFrontCookieSigner类。使用这个类和方法,我们可以生成cookie。

  1. CloudFront的签名
  2. CloudFront的-政策
  3. CloudFront的-密钥对-ID

    请注意,Java仅支持DER格式的SSL证书,因此您需要将PEM格式的文​​件转换为DER格式。

    为此,您可以使用openssl:

  4. 从.pem

    生成.der文件的命令
    openssl pkcs8 -topk8 -nocrypt -in origin.pem -inform PEM -out new.der -outform DER 
    

    参考: - 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();
            }