<p><a href="http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls-overview.html" rel="nofollow noreferrer">Amazon CloudFront Signed URLs</a>工作方式与Amazon S3签名的url不同。CloudFront使用基于单独的CloudFront密钥对的RSA签名,您必须在Amazon帐户凭据页中设置该密钥对。下面是一些代码,可以使用<a href="https://pypi.python.org/pypi/M2Crypto" rel="nofollow noreferrer">M2Crypto</a>库在Python中实际生成一个有时间限制的URL:</p>
<p><strong>为CloudFront创建密钥对</strong></p>
<p>我认为唯一的办法就是通过亚马逊的网站。进入你的AWS“账户”页面,点击“安全凭证”链接。单击“密钥对”选项卡,然后单击“创建新密钥对”。这将为您生成新的密钥对并自动下载私钥文件(pk-xxxxxxxxx.pem)。保持密钥文件的安全性和私密性。还要记下亚马逊的“密钥对ID”,因为我们下一步需要它。</p>
<p><strong>用Python生成一些url</p>
<p>从boto版本2.0开始,似乎不支持生成签名的CloudFront url。Python在标准库中不包含RSA加密例程,因此我们将不得不使用一个附加库。我在这个例子中使用了M2Crypto。</p>
<p>对于非流媒体分发,您必须使用完整的cloudfront URL作为资源,但是对于流媒体,我们仅使用视频文件的对象名称。有关生成仅持续5分钟的URL的完整示例,请参见下面的代码。</p>
<p>此代码松散地基于Amazon在CloudFront文档中提供的PHP示例代码。</p>
<pre><code>from M2Crypto import EVP
import base64
import time
def aws_url_base64_encode(msg):
msg_base64 = base64.b64encode(msg)
msg_base64 = msg_base64.replace('+', '-')
msg_base64 = msg_base64.replace('=', '_')
msg_base64 = msg_base64.replace('/', '~')
return msg_base64
def sign_string(message, priv_key_string):
key = EVP.load_key_string(priv_key_string)
key.reset_context(md='sha1')
key.sign_init()
key.sign_update(message)
signature = key.sign_final()
return signature
def create_url(url, encoded_signature, key_pair_id, expires):
signed_url = "%(url)s?Expires=%(expires)s&Signature=%(encoded_signature)s&Key-Pair-Id=%(key_pair_id)s" % {
'url':url,
'expires':expires,
'encoded_signature':encoded_signature,
'key_pair_id':key_pair_id,
}
return signed_url
def get_canned_policy_url(url, priv_key_string, key_pair_id, expires):
#we manually construct this policy string to ensure formatting matches signature
canned_policy = '{"Statement":[{"Resource":"%(url)s","Condition":{"DateLessThan":{"AWS:EpochTime":%(expires)s}}}]}' % {'url':url, 'expires':expires}
#sign the non-encoded policy
signature = sign_string(canned_policy, priv_key_string)
#now base64 encode the signature (URL safe as well)
encoded_signature = aws_url_base64_encode(signature)
#combine these into a full url
signed_url = create_url(url, encoded_signature, key_pair_id, expires);
return signed_url
def encode_query_param(resource):
enc = resource
enc = enc.replace('?', '%3F')
enc = enc.replace('=', '%3D')
enc = enc.replace('&', '%26')
return enc
#Set parameters for URL
key_pair_id = "APKAIAZVIO4BQ" #from the AWS accounts CloudFront tab
priv_key_file = "cloudfront-pk.pem" #your private keypair file
# Use the FULL URL for non-streaming:
resource = "http://34254534.cloudfront.net/video.mp4"
#resource = 'video.mp4' #your resource (just object name for streaming videos)
expires = int(time.time()) + 300 #5 min
#Create the signed URL
priv_key_string = open(priv_key_file).read()
signed_url = get_canned_policy_url(resource, priv_key_string, key_pair_id, expires)
print(signed_url)
#Flash player doesn't like query params so encode them if you're using a streaming distribution
#enc_url = encode_query_param(signed_url)
#print(enc_url)
</code></pre>
<p>请确保使用TrustedSigners参数设置为持有密钥对的帐户(如果是您自己的帐户,则为“Self”)来设置分发</p>
<p>请参阅<a href="https://stackoverflow.com/questions/6549787/getting-started-with-secure-aws-cloudfront-streaming-with-python/6590986#6590986">Getting started with secure AWS CloudFront streaming with Python</a>以获取有关使用Python设置流的完整示例</p>