Amazon Cloudfront 签名 URL 访问被拒绝问题

Posted

技术标签:

【中文标题】Amazon Cloudfront 签名 URL 访问被拒绝问题【英文标题】:Amazon Cloudfront Signed URL Access denied issue 【发布时间】:2013-01-03 18:20:37 【问题描述】:

我正在尝试为我的 S3 存储桶中的内容构建 Amazone cloudfront 的签名 URL。我已按照从 amazone aws 文档(http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html#private-content-custom-policy-creating-signature-download-procedure)构建签名 url 的程序进行操作,但我正在构建的 url 的某些原因是收到此消息“AccessDeniedAccess denied”。

我还从 Distribution SettingsBehaviors 中将“Trusted Signers”添加为“self”,并为那个分布。我不确定我错过了什么。这是我的php代码

<?php

    function rsa_sha1_sign($policy, $private_key_filename) 
    
        $signature = "";

        // load the private key
        $fp = fopen($private_key_filename, "r");
        $priv_key = fread($fp, 8192);
        fclose($fp);
        //echo $priv_key;
        $pkeyid = openssl_get_privatekey($priv_key);

        // compute signature
        openssl_sign($policy, $signature, $pkeyid);

        // free the key from memory
        openssl_free_key($pkeyid);
        //echo $signature;
        return $signature;
     

    function url_safe_base64_encode($value) 
    
        $encoded = base64_encode($value);
        // replace unsafe characters +, = and / with 
        // the safe characters -, _ and ~
        return str_replace(
            array('+', '=', '/'),
            array('-', '_', '~'),
            $encoded);
     

    $key_pair_id = "MY_KEY_PAIR_ID";
    $donwload_cname = "MY_DOWNLOAD_CNAME";
    $download_url = "MY_DOMAIN_NAME/download/2012/01/FILE_NAME.mp3";

    $DateLessThan = time() + (24*7*60*60);
    $policy = '"Statement":["Resource":"'.$download_url.'","Condition":"DateLessThan":"AWS:EpochTime":'.$DateLessThan.']';

    $private_key_file = "MY_PRIVATE_KEY_FILE.pem";

    $signature = rsa_sha1_sign($policy, $private_key_file);
    $signature = url_safe_base64_encode($signature);

    $final_url = $download_url.'?Policy='.url_safe_base64_encode($policy).'&Signature='.$signature.'&Key-Pair-Id='.$key_pair_id;
    echo $final_url;

?>

我已尝试使用 download_url 的域名和 cname 但没有效果。那就是我尝试了两种url格式

$download_url = "MY_DOMAIN_NAME/download/2012/01/FILE_NAME.mp3" 
$download_url = "MY_DOWNLOAD_CNAME/download/2012/01/FILE_NAME.mp3" 

但没有任何工作。谁可以帮我这个事 。我确信这里缺少一些非常小的东西,或者需要对存储桶设置进行一些处理,但现在不知道该怎么做。急需帮助

【问题讨论】:

【参考方案1】:

您还必须在下载 URL 中添加协议(http:// 或 https://)。因为有和没有那个的签名会有所不同。 云前端后端可能正在使用完整的 URL(带有 http:// 或 https://)生成签名,并且签名与您的不匹配,并且您收到拒绝访问错误。

使您的下载网址如下所示,

$download_url = "http://MY_DOMAIN_NAME/download/2012/01/FILE_NAME.mp3"

或用于 https://

$download_url = "https://MY_DOMAIN_NAME/download/2012/01/FILE_NAME.mp3"

【讨论】:

有类似的问题。通过正确转义网址来解决它。例如:“MY_DOMAIN_NAME/download/2012/01/FILE_NAME.mp3”应该是“MY_DOMAIN_NAME/download/2012/01/FILE_+NAME.mp3”空格应该用+而不是%20或空格来转义

以上是关于Amazon Cloudfront 签名 URL 访问被拒绝问题的主要内容,如果未能解决你的问题,请参考以下文章

为 Amazon CloudFront 创建签名 URL

Amazon CloudFront - 使用签名 URL 保护视频

使用 Ruby 为 CloudFront 创建签名 URL

Amazon S3 无法通过 Cloudfront 上传文件

Amazon s3 预签名 URL 受 IP 地址限制

如何使用预设策略加密 Amazon CloudFront 签名以进行私有内容访问