Отказ в доступе из Cloudfront с безопасными файлами cookie не возвращает заголовки CORS, препятствующие считыванию информации об ошибке из запроса XHR.

avatar
cowmix
8 апреля 2018 в 03:11
1143
1
2

Я использую облачные защищенные файлы cookie, чтобы сохранить конфиденциальность некоторых файлов. Когда проверка подлинности файлов cookie завершается успешно, и источник попадает в облачный фронт, он возвращает правильные заголовки cors (Access-Control-Allow-Origin) из источника, но как мне заставить облачный фронт возвращать заголовки CORS во время 403/Отказано в доступе? Эта проверка выполняется полностью в облаке перед запросом к источнику, но есть ли настройка для ее включения? Я хочу иметь возможность отправить XHR-запрос в облачный сервис и узнать, почему запрос не удался. Поскольку Cloudfront не возвращает заголовки cors на 403, большинство современных браузеров не смогут прочитать любую информацию о запросе, включая код состояния, и будет сложно определить, почему запрос не удался.

Спасибо!

Источник
Michael - sqlbot
8 апреля 2018 в 05:12
0

Итак, вам нужны заголовки CORS только для того, чтобы программно увидеть ошибку 403?

cowmix
8 апреля 2018 в 05:21
0

@Michael-sqlbot да, я хочу знать, действительна ли это ошибка 403 или аутентификация, и это ошибка 404.

Ответы (1)

avatar
Michael - sqlbot
8 апреля 2018 в 14:19
3

Как вы знаете, CloudFront не генерирует заголовки CORS спонтанно — они должны поступать с исходного сервера — поэтому, чтобы увидеть заголовки CORS в ответе, запрос должен быть разрешен CloudFront... но , конечно, это не может быть разрешено, потому что условие, которое вы пытаетесь поймать, это 403 Forbidden.

Итак, чтобы ваши неавторизованные ответы были совместимы с CORS, нам нужен дополнительный источник, который может предоставить нам альтернативный ответ об ошибке, и этот источник должен поддерживать CORS. Решение похоже на то, что мы можем решить с небольшой помощью CloudFront Custom Error Responses и пустой корзины S3, созданной для этой цели.

Пользовательские ответы об ошибках позволяют настроить CloudFront для получения пользовательского ответа об ошибке из другого источника, а не создавать его внутри. В рамках этого процесса некоторые заголовки из исходного запроса включаются в восходящую выборку, и возвращаются заголовки ответа из документа об ошибке.

S3 является удобным источником, поскольку он имеет настраиваемую поддержку CORS.

  • Создайте новый пустой сегмент.
  • Включите CORS для корзины и настройте CORS с соответствующими параметрами. Конфигурация по умолчанию может подойти для этой цели.
  • Создайте простой файл, который будет использоваться вашей базой раздачи CloudFront вместо встроенного ответа на ошибку 403. В целях тестирования это может быть просто текстовый файл с надписью «Отказано в доступе».
  • Загрузите файл в корзину под любым именем, например 403.txt. Выберите параметр, чтобы сделать объект общедоступным для чтения. Установите метаданные Cache-Control: no-cache, no-store, private, must-revalidate и Content-Type: text/plain (или text/html, в зависимости от того, что именно вы указали в файле ошибки).
  • В CloudFront создайте новый источник. В качестве имени исходного домена выберите сегмент из списка сегментов.
  • Создайте новое поведение кэша, соответствующее пути /403.txt (или как вы назвали файл). Внесите в белый список заголовки Origin, Access-Control-Request-Headers и Access-Control-Request-Method для пересылки. Установите для параметра «Ограничить доступ средства просмотра» значение «Нет», поскольку для этого пути нам не требуются подписанные учетные данные. Обратите внимание, что этот путь должен точно совпадать с именем файла в корзине (кроме косой черты в начале, которая не отображается в корзине, но должна быть включена здесь).
  • В CloudFront Custom Error Responses выберите Create Custom Error Response. Выберите код ошибки 403, установите для минимального срока жизни при кэшировании ошибок значение 0, выберите «Настроить ответ на ошибку «Да», установите путь страницы ответа /403.txt и установите код ответа HTTP на 403.
  • Прибыль!

Тест:

$ curl -v dzczcnnnnexample.cloudfront.net -H 'Origin: http://example.com'
* Rebuilt URL to: dzczcnnnnexample.cloudfront.net/
*   Trying 203.0.113.208...
* Connected to dzczcnnnnexample.cloudfront.net (203.0.113.208) port 80 (#0)
> GET / HTTP/1.1
> Host: dzczcnnnnexample.cloudfront.net
> User-Agent: curl/7.47.0
> Accept: */*
> Origin: http://example.com
>
< HTTP/1.1 403 Forbidden
< Content-Type: text/plain
< Content-Length: 16
< Connection: keep-alive
< Date: Sun, 08 Apr 2018 14:01:25 GMT
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, HEAD
< Access-Control-Max-Age: 3000
< Last-Modified: Sun, 08 Apr 2018 13:29:19 GMT
< ETag: "fd9e8f7be7b65381c4acc272b6afc858"
< x-amz-server-side-encryption: AES256
< Cache-Control: private, no-cache, no-store, must-revalidate
< Accept-Ranges: bytes
< Server: AmazonS3
< Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
< X-Cache: Error from cloudfront
< Via: 1.1 1234567890a26beddeac6bfc77b2d348.cloudfront.net (CloudFront)
< X-Amz-Cf-Id: ExAmPlEIbQBtaqExamPLEQs4VwcxhvtU1YXBi47uUzUgami0Hj0MwQ==
<
Access denied.
* Connection #0 to host dzczcnnnnexample.cloudfront.net left intact

Вот, Access denied. — это то, что я поместил в созданный мной текстовый файл. Возможно, вы захотите проявить немного больше творчества, убедившись, что это работает для вас, как и для меня. Содержимое этого нового файла в S3 всегда будет возвращаться всякий раз, когда CloudFront выдает ошибку 403. Кроме того, он также будет возвращен всякий раз, когда ваш источник выдает ошибку 403, поскольку настраиваемые ответы об ошибках предназначены для замены всех ошибок заданным кодом состояния HTTP.

Вы заметили выше, что мы видим Access-Control-Allow-Origin: *. Это поведение S3 CORS по умолчанию. Если вы укажете явное происхождение в конфигурации S3 CORS, вы получите такой ответ...

Access-Control-Allow-Origin: http://example.com

... но для запросов GET я предполагаю, что этот уровень специфичности не нужен, и подстановочного знака будет достаточно. Описанный здесь сценарий не устанавливает CORS для всей раздачи CloudFront — только для ответа на ошибку.