Presigned URL в S3 возвращает 403: как найти причину

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

Сайт выдал ссылку на файл в S3, но скачивание заканчивается 403. Сначала прочитайте код ошибки в ответе хранилища: истёкший доступ, несовпадение подписи и запрет операции требуют разных исправлений.

Presigned URL — временная подписанная ссылка. Проверяйте её срок, затем точное соответствие запроса подписи и права выдавшего ссылку приложения. Ниже — порядок для Amazon S3; у S3-совместимого провайдера сверяйте названия ошибок и ограничения с его документацией.

1. Зафиксируйте отказ без утечки ссылки

В Network инструментов разработчика выберите запрос к файлу. Запишите HTTP-статус, метод, время с часовым поясом и поле Code из ответа, если оно доступно. Отдельно отметьте, отказало скачивание или загрузка.

Не отправляйте полный presigned URL в публичный проверяющий сервис, чат или скриншот: владение ссылкой даёт доступ в пределах её разрешений. Для обсуждения достаточно обезличенного пути, кода ошибки и времени; подпись и параметры доступа удалите.

Сравните два случая: свежая ссылка сразу после выдачи и ссылка из ранее открытой страницы. Это разделяет сбой формирования запроса и проблему старого адреса в интерфейсе. Если ответ пришёл от прокси, а не S3, начните с его журналов; общий маршрут есть в разборе 403 Forbidden.

2. Если доступ истёк — проверьте два срока

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

Проверьте время создания ссылки, заданный срок и окончание сессии роли на стороне приложения. Обновите временные учётные данные штатным механизмом SDK и только затем выдайте новый URL. Увеличение срока ссылки не продлевает сессию роли.

S3 проверяет срок при начале запроса: уже начатое скачивание может продолжаться после истечения, но повторное скачивание — завершиться отказом. Эти ограничения описаны в документации AWS о presigned URL.

3. Если SignatureDoesNotMatch — сравните исходный и отправленный запрос

Метод и заголовки

Ссылка для загрузки через PUT не становится ссылкой для скачивания через GET. Проверка через HEAD также не воспроизводит подписанный GET. Зафиксируйте метод, который задал генератор, и метод фактического запроса.

Если при подписи загрузки указан Content-Type, отправляйте то же значение. Например, подпись для image/png и отправка с application/octet-stream — повод проверить расхождение. Не меняйте заголовки наугад: сопоставьте настройки генератора и клиента.

Адрес, регион и часы

  1. Возьмите адрес непосредственно из ответа приложения, без ручной сборки.
  2. Проверьте, не обрезались ли параметры после &, не изменились ли экранирование и путь при вставке в HTML или обработке фронтендом.
  3. Сверьте регион бакета в настройках SDK. Не заменяйте домен выданной ссылки на собственный CDN-домен.
  4. Проверьте синхронизацию часов сервера, который создаёт подпись.

AWS отдельно указывает на неизменность URL, совпадение типа содержимого, регион и системное время в инструкции по подписанной загрузке. Исправляйте один обнаруженный фактор, затем повторяйте проверку на новой ссылке.

4. Если AccessDenied — проверьте разрешения операции

Корректная подпись не отменяет правила доступа. Администратору нужно проверить право нужной роли на конкретный объект и действие: например, s3:GetObject для чтения. Явный запрет в применимой политике может блокировать запрос при наличии разрешения в другой.

Дальше проверяют политики бакета, ограничения сетевого доступа и, для объектов с SSE-KMS, права на ключ шифрования. Разные причины одинакового 403 перечислены в руководстве AWS по AccessDenied.

Не делайте бакет публичным и не выдавайте административные права ради проверки. Найдите конкретное запрещающее условие; изменение должно разрешить требуемую операцию, сохранив остальные ограничения.

5. Подтвердите исправление в пользовательском сценарии

Проверяйте на небольшом тестовом объекте без персональных данных. Для загрузки выделите отдельный ключ: PUT может заменить существующий объект. Успех означает, что нужная операция выполнилась и файл соответствует ожидаемому, а не только то, что приложение смогло выдать строку URL.

Если клиент вне браузера выполняет запрос, а страница нет, сравните методы и заголовки; отдельно проверьте CORS и запрос OPTIONS. Не объявляйте подпись исправной лишь потому, что другая операция прошла.

Обычный мониторинг публичной страницы в Web-Puls помогает заметить её недоступность, но не доказывает работоспособность выдачи приватных файлов. Для этого нужен отдельный контролируемый сценарий получения свежей ссылки и выполнения разрешённой операции; хранить одну истекающую ссылку как постоянный адрес проверки неудобно и небезопасно.

Если причина остаётся неясной, отправьте заявку на диагностику: укажите провайдера, операцию, обезличенный код ошибки, время и результаты проверки свежей ссылки. Полный подписанный URL и ключи доступа не прикладывайте; по описанию специалист сможет оценить задачу и предложить формат работ.

Мониторинг сайтов

Если сайт или отдельные страницы отдают 403 Forbidden, причина может быть в правах доступа, защите CDN, правилах firewall или конфигурации сервера. Ниже — короткий маршрут проверки, примеры и следующий шаг: внешняя диагностика или заявка в поддержку.

Проверьте свой сайт прямо сейчас

Введите адрес сайта: Web-Puls покажет HTTP-код, время ответа и базовую диагностику. Для постоянного контроля можно подключить мониторинг.

Нужна помощь с диагностикой ошибки?

Опишите симптомы в короткой заявке: URL, код ответа, время появления и что менялось перед сбоем. Специалист поддержки оценит задачу и предложит формат работ.