Мне нужно создать подписанный URL для загрузки файла в корзину s3.
Ключ файла s3 должен быть его sha256
хешем.
Тогда возникает вопрос: как я могу убедиться, что клиент отправляет действительный хэш? Я создаю подписанный URL-адрес в своей функции лямбда-выражения и не пропускаю через нее файл, поэтому лямбда-выражение, конечно, не может вычислить хэш.
Я думаю, что могу добиться этого, используя 2 шага:
Принудительно отправляет клиенту свои расчетные sha256
с загрузкой. Исходя из спецификации, я предполагаю, что это будет автоматически проверено при предоставлении его в заголовке x-amz-content-sha256
.
Заставить клиента отправлять тот же хэш лямбде, чтобы я мог заставить его быть ключом.
Сначала я попробовал это:
s3.getSignedUrl('putObject', { Key: userProvidedSha256 }, callback)
Я попытался добавить условие типа { header: { 'X-Amz-Content-Sha256': userProvidedSha256 } }
.
Но я не нашел способа добавить такое определение, чтобы оно фактически заставляло клиента отправлять заголовок X-Amz-Content-Sha256
.
Кроме того, я бы применил тот же подход для обеспечения фиксированного требуемого заголовка Content-Length
(клиент отправляет желаемую длину на сервер, там мы его подписываем), но не уверен, что это сработает из-за этой проблемы .
Поскольку я обнаружил, что s3.createPresignedPost
также позволяет мне ограничивать максимальный размер вложения и выглядит более гибким, я пошел по этому пути:
const signPostFile = () => {
const params = {
Fields: {
key: userProvidedSha256
},
Expires: 86400,
Conditions: [
['content-length-range', 0, 10000000],
{ 'X-Amz-Content-Sha256': userProvidedSha256]
]
}
s3.createPresignedPost(params, callback)
}
Но пока это работает (это заставляет клиента отправлять принудительный заголовок sha256, и заголовок передается, см. Журнал запросов ниже), похоже, что клиент теперь должен добавить x-amz-content-sha256
в поля формы, а не заголовок Это выглядит так, как задумано, но ясно, что s3 не будет сравнивать представленный файл с предоставленным sha256: любой файл, который я добавляю в форму, успешно загружен, даже если sha256 не соответствует.
Есть ли какие-либо предположения о том, что не так или как еще можно применить условие sha256, одновременно ограничивая длину содержимого?
Обновление: я использую подпись v4, и я попробовал политику S3 Deny
для этого условия:
Condition:
StringEquals:
s3:x-amz-content-sha256: UNSIGNED-PAYLOAD
Соответствующий журнал запросов на отправку файла, содержащего строку «hello world»:
----------------------------986452911605138616518063
Content-Disposition: form-data; name="X-Amz-Content-Sha256"
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
----------------------------986452911605138616518063
Content-Disposition: form-data; name="key"
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9