Подписанные URL-адреса Amazon CloudFront работают иначе, чем подписанные URL-адреса Amazon S3. CloudFront использует подписи RSA на основе отдельной пары ключей CloudFront, которую необходимо настроить на странице «Учетные данные учетной записи Amazon». Вот некоторый код для создания ограниченного по времени URL-адреса в Python с использованием библиотеки M2Crypto :
Создание пары ключей для CloudFront
Я думаю, что единственный способ сделать это - через веб-сайт Amazon. Перейдите на страницу своей учетной записи AWS и нажмите ссылку «Учетные данные безопасности». Нажмите на вкладку «Пары ключей», затем нажмите «Создать новую пару ключей». Это создаст новую пару ключей для вас и автоматически загрузит файл закрытого ключа (pk-xxxxxxxxx.pem). Храните файл ключа в секрете. Также запишите «Идентификатор пары ключей» от Amazon, так как он понадобится нам на следующем шаге.
Создание некоторых URL в Python
Начиная с версии 2.0 boto, похоже, что поддержка создания подписанных URL-адресов CloudFront не поддерживается. Python не включает процедуры шифрования RSA в стандартную библиотеку, поэтому нам придется использовать дополнительную библиотеку. Я использовал M2Crypto в этом примере.
Для не потокового распространения вы должны использовать полный URL-адрес облачного фронта в качестве ресурса, однако для потоковой передачи мы используем только имя объекта видеофайла. В приведенном ниже коде приведен полный пример создания URL-адреса, который длится всего 5 минут.
Этот код основан на примере PHP-кода, предоставленного Amazon в документации CloudFront.
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)
Убедитесь, что вы настроили свой дистрибутив с параметром TrustedSigners, установленным для учетной записи, содержащей вашу пару ключей (или "Self", если это ваша собственная учетная запись)
См. Начало работы с безопасной потоковой передачей AWS CloudFront с Python , чтобы получить полностью проработанный пример настройки этой функции для потоковой передачи с Python