#node.js #https #amazon-cloudfront #signed-url
Вопрос:
Я настроил 4 дистрибутива CloudFront, все из которых имеют одинаковое происхождение S3 и имеют политику протокола просмотра: HTTP и HTTPS. Их отличие заключается в Альтернативных доменных именах и ограничении доступа зрителей.
- Распространение 1: Альтернативные Доменные Имена: Нет, Ограничение Доступа для просмотра: Нет
- Распределение 2: Альтернативные Доменные Имена: Нет, Ограничение Доступа к Просмотрщику: Да
- Распределение 3: Альтернативные Доменные Имена: distribution3.example.com, Ограничить Доступ к Просмотрщику: Нет
- Распределение 4: Альтернативные Доменные Имена: distribution4.example.com, Ограничить Доступ к Просмотрщику: Да
Я загрузил изображение в корзину S3 (доступ к нему заблокирован) и попытался получить к нему доступ с помощью дистрибутивов CloudFront. При подписании URL-адреса я использовал одно и то же значение для истечения срока действия (через неделю), использовал один и тот же открытый ключ в одной и той же группе доверенных ключей и подписал все URL-адреса одним и тем же кодом (с помощью политики сохранения). Мой домен зарегистрирован в Cloudflare, и его сертификат HTTPS выдается Amazon в диспетчере сертификатов AWS. Вот результаты:
Распространение 1: Альтернативные Доменные Имена: Нет, Ограничение Доступа для просмотра: Нет
http://distribution1.cloudfront.net/image.jpg -> 200 OK
https://distribution1.cloudfront.net/image.jpg -> 200 OK
Распределение 2: Альтернативные Доменные Имена: Нет, Ограничение Доступа к Просмотрщику: Да
http://distribution2.cloudfront.net/image.jpg -> 403 Forbidden
https://distribution2.cloudfront.net/image.jpg -> 403 Forbidden
http://distribution2.cloudfront.net/image.jpg?Expires=XXXamp;Signature=XXXamp;Key-Pair-Id=XXX -> 200 OK
https://distribution2.cloudfront.net/image.jpg?Expires=XXXamp;Signature=XXXamp;Key-Pair-Id=XXX -> 200 OK
Распределение 3: Альтернативные Доменные Имена: distribution3.example.com, Ограничить Доступ к Просмотрщику: Нет
http://distribution3.cloudfront.net/image.jpg -> 200 OK
https://distribution3.cloudfront.net/image.jpg -> 200 OK
http://distribution3.example.com/image.jpg -> 200 OK
https://distribution3.example.com/image.jpg -> 200 OK
Распределение 4: Альтернативные Доменные Имена: distribution4.example.com, Ограничить Доступ к Просмотрщику: Да
http://distribution4.cloudfront.net/image.jpg -> 403 Forbidden
https://distribution4.cloudfront.net/image.jpg -> 403 Forbidden
http://distribution4.example.com/image.jpg -> 403 Forbidden
https://distribution4.example.com/image.jpg -> 403 Forbidden
http://distribution4.cloudfront.net/image.jpg?Expires=XXXamp;Signature=XXXamp;Key-Pair-Id=XXX -> 200 OK
https://distribution4.cloudfront.net/image.jpg?Expires=XXXamp;Signature=XXXamp;Key-Pair-Id=XXX -> 200 OK
http://distribution4.example.com/image.jpg?Expires=XXXamp;Signature=XXXamp;Key-Pair-Id=XXX -> 200 OK
https://distribution4.example.com/image.jpg?Expires=XXXamp;Signature=XXXamp;Key-Pair-Id=XXX -> 403 -> Access denied XML page. WHY?
Почему последнее дело провалилось? Я что-то упускаю?
Код nodejs, используемый для создания подписанного URL-адреса, одинаков для всех:
fs = require('fs')
crypto = require('crypto')
const EXPIRES = 1624235093 // Mon Jun 21 2021 00:24:53 GMT 0000
const KEY_PAIR_ID = 'KUXXX' // Cloudfront -> Key management -> Public keys
const privateKey = fs.readFileSync('private_key.pem', 'utf8')
// Creating a signed URL using a canned policy
// https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-canned-policy.html
function createSignedURL(baseURL) {
// canned policy
const cannedPolicy = {
"Statement": [
{
"Resource": baseURL,
"Condition": {
"DateLessThan": {
"AWS:EpochTime": EXPIRES
}
}
}
]
}
// Remove white space (including tabs and newline characters) from the policy string
const cannedPolicyString = JSON.stringify(cannedPolicy).replace(/[stnr]/g, '')
// console.log(cannedPolicyString);
// Sign policy with private key using RSA-SHA1,
// Base64-encode the string,
// Remove white space (including tabs and newline characters) from the hashed and signed string
// Replace characters that are invalid in a URL query string with characters that are valid.
const sign = crypto.createSign('RSA-SHA1')
sign.update(cannedPolicyString)
sign.end()
const signature = sign.sign(privateKey, 'base64').replace(/ /g, '-').replace(/=/g, '_').replace(///g, '~')
// console.log(signature);
// Creating a signed URL
const signedURL = `${ baseURL }?Expires=${ EXPIRES }amp;Signature=${ signature }amp;Key-Pair-Id=${ KEY_PAIR_ID }`
// console.log(signedURL);
// return
return signedURL
}
console.log(createSignedURL('https://distribution4.example.com/image.jpg'));
Комментарии:
1. Не могли бы вы опубликовать код, который генерирует URL-адрес с подписью председателя, в дистрибутиве 4?
2. @jellycsc Я добавил код. Это было одинаково для всех сгенерированных подписей. Все они работали, кроме последнего.
3. Похоже, что вы подписываете http://, но пытаетесь получить доступ через http S ://
4. @anasqadrei Вы можете подтвердить, что подписываете https-версию URL-адреса^^?
5. @StefanN моя функция createSignedURL подписывает любой URL, который она получает, будь то http или https. Я подписываю протокол https и получаю доступ к протоколу https