Предварительно подписанный URL-адрес S3 без пути

Мне нужен способ разрешить клиенту загружать данные в S3, не показывая им полное местоположение (путь) файла. Можно ли это сделать с предварительно подписанным URL-адресом AWS S3?

Я использую boto3 как таковой

s3.client.generate_presigned_url(
  ClientMethod='put_object', 
  ExpiresIn=7200,
  Params={'Bucket': BUCKET, 'Key': name}
)

Но результат будет таким:

https://s3.amazonaws.com/MY_BUCKET/upload/xxxx-xxxx/file-name.bin?AWSAccessKeyId=XXXX&Signature=XXXX&Expires=XXXX

Мне нужно что-то подобное, чтобы не отображать имя ключа в пути (/upload/xxxx-xxxx/file-name.bin).

Какие еще решения у меня есть, если не предварительно подписанный URL?


person JBernardo    schedule 28.02.2019    source источник
comment
Я просто подбрасываю идею: у вас может быть тривиальная функция Lambda, которая запускается при загрузке, а затем перемещает / переименовывает загруженный объект.   -  person Alexander Azarov    schedule 28.02.2019
comment
@AlexanderAzarov Именно того, чего я пытаюсь избежать, но я полагаю, что смогу это сделать   -  person JBernardo    schedule 28.02.2019
comment
Здесь может пригодиться Lambda @ edge.   -  person Pubudu Jayawardana    schedule 28.02.2019
comment
Есть ли какая-то конкретная причина, по которой вы не хотите, чтобы они видели путь / ключ? Знание этого не дает им никакого дополнительного доступа.   -  person John Rotenstein    schedule 01.03.2019
comment
@JohnRotenstein Я знаю, но из-за некоторого устаревшего кода этот путь открыт для другого приложения. До тех пор, пока мы не сможем полностью перенести клиентов и еще много чего, нужно скрывать это.   -  person JBernardo    schedule 01.03.2019


Ответы (2)


Я считаю, что лучший способ - это распространять файлы с помощью AWS Cloudfront. Вы можете установить источник распространения Cloudfront на MY_BUCKET.s3.amazonaws.com. Также можно использовать вложенные папки, такие как MY_BUCKET.s3.amazonaws.com/upload, в качестве источника.

Cloudfront будет обслуживать ваши файлы в источнике S3 с сгенерированным доменом конечной точки CDN, или также можно установить и использовать собственный домен.

https://d111111abcdef8.cloudfront.net/upload/xxxx-xxxx/file-name.bin https://uploads.example.com/upload/xxxx-xxxx/file-name.bin

если вы используете подпапку в качестве источника:

https://uploads.example.com/xxxx-xxxx/file-name.bin


Дополнительная информация о настройке S3 Bucket в качестве источника в Cloudfront: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistS3AndCustomOrigins.html#concept_S3Origin

Дополнительная информация об использовании путей к каталогам S3 Bucket в качестве источника: https://aws.amazon.com/about-aws/whats-new/2014/12/16/amazon-cloudfront-now-allows-directory-path-as-origin-name/

Дополнительная информация о настраиваемых URL-адресах: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html

person grgizem    schedule 04.03.2019
comment
Конечно, я использую облачный интерфейс для взаимодействия с S3, и это не помогает мне решить проблему с загрузкой. - person JBernardo; 09.03.2019

Это неполный ответ, но он слишком длинный, чтобы быть комментарием.

Я думаю, вы сможете использовать API Gateway в качестве прокси для S3, чтобы скрыть путь. Вы по-прежнему можете использовать предварительно подписанные URL-адреса, но вам может потребоваться создать предварительно подписанные URL-адреса шлюза API, а не предварительно подписанные URL-адреса S3. Я никогда не делал этого сам - и не смогу опробовать это в ближайшем будущем - но я сделаю все возможное, чтобы изложить, как я думаю, что это делается, и, может быть, кто-то еще может попробовать это и написать более полный отвечать.

Во-первых, нам нужно настроить конечную точку шлюза API, которая будет действовать как прокси для S3.

У AWS есть очень подробное описание как создать общий прокси для S3, и я думаю, что вы можете сделать свою настраиваемую конечную точку точкой для определенного сегмента и папки в S3, изменив PathOverride прокси. Если вы посмотрите на снимок экрана PathOverrides в этот раздел документации AWS, вы можете видеть, что они установили переопределение пути на {bucket}/{object}, но я думаю, что вы могли бы установите PathOverride на mySecretBucket/my/secret/folder/{object}, а затем обновите сопоставления путей соответствующим образом.

Затем вам нужно иметь возможность использовать предварительно подписанные URL-адреса с этим прокси. Это можно сделать двумя способами.

Первое, что может сработать, - это передать подпись URL-адреса через API-шлюз на S3. Я знаю, что можно сопоставить параметры запроса аналогично параметрам пути. Возможно, вам потребуется выполнить некоторую кодировку URL-адреса для параметра подписи предварительно подписанного URL-адреса, чтобы заставить его работать - я не совсем уверен.

Другой вариант - разрешить Api Gateway всегда писать на S3 и потребовать подписанный запрос для вызова вашей конечной точки прокси. На этот вопрос SO есть довольно подробный ответ, который выглядит мне вроде должно работать.

Опять же, я знаю, что это неполный ответ, и я не пытался проверить, работает ли это, но, надеюсь, кто-нибудь сможет начать с этого и получить полный ответ на ваш вопрос.

person Matthew Pope    schedule 03.03.2019
comment
Я не удовлетворен, но, по крайней мере, вы предоставили что-то другое, кроме лямбды, что кажется разумным. Я даю вам награду, но пока оставляю вопрос открытым - person JBernardo; 09.03.2019
comment
Это честно. Это не очень удовлетворительное решение. Похоже, что для AWS должна быть довольно простой функцией добавлять обфусцированные предварительно подписанные ссылки; Не знаю, почему они этого не поддерживают. - person Matthew Pope; 09.03.2019