5

Я пытаюсь изящно обрабатывать 403 при посещении ресурса S3 по истекшему URL. В настоящее время он возвращает страницу ошибки amz xml. Я загрузил ресурс 403.html и думал, что могу перенаправить на него.AWS S3 изящно обрабатывает 403 после того, как getSignedUrl истекло

Ресурсы ведра - это активы, сохраненные/извлеченные моим приложением. Тем не менее, читая документы, я задал свойства ведра для обработки ведра как статической страницы веб-страницы и загрузил файл 403.html в корневой каталог. Все общедоступные разрешения блокируются, за исключением открытого доступа GET к ресурсу 403.html. В свойствах bucket, настройках веб-сайта я указал страницу 403.html как страницу с ошибкой. Посещение http://<bucket>.s3-website-us-east-1.amazonaws.com/some-asset.html перенаправляет правильно http://<bucket>.s3-website-us-east-1.amazonaws.com/403.html

Однако, когда я использую AWS-SDk JS/узел и способ вызова getSignedUrl('getObject', params) для создания подписанного URL, он возвращает другой хост URL: https://<bucket>.s3.amazonaws.com/ приглашенных истек ресурсы этого метода не попадают в 403.html. Я предполагаю, что, поскольку адрес хоста отличается, это причина, по которой он не перенаправляется автоматически.

Я также настроить статические правила маршрутизации для сайта условия

<Condition> 
    <HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals> 
</Condition> 
<Redirect> 
    <ReplaceKeyWith>403.html</ReplaceKeyWith> 
</Redirect> 

Тем не менее, что не перенаправляет подписанные URLs. Поэтому я не понимаю, как грациозно обрабатывать эти устаревшие URL-адреса. Любая помощь будет принята с благодарностью.

ответ

9

S3 ведра имеют 2 открытых интерфейса, REST и веб-сайт. В этом разница между двумя именами хостов и различием в поведении, которое вы видите.

У них есть два разных набора функций.

feature   REST Endpoint  Website Endpoint 
---------------- ------------------- ------------------- 
Access control yes     no, public content only 
Error messages XML     HTML 
Redirection  no     yes, bucket, rule, and object-level 
Request types all supported  GET and HEAD only 
Root of bucket lists keys   returns index document 
SSL    yes     no 

Источник: http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html

Итак, как вы можете видеть из таблицы, конечная точка REST поддерживает подписанные URL-адреса, но не дружественные ошибок, в то время как веб-сайт конечных точек поддерживает дружественные ошибки, но не подписанные URL. Эти два нельзя смешивать и сопоставлять, поэтому то, что вы пытаетесь сделать, не поддерживается S3.


Я работал вокруг этого ограничения, передавая все запросы на ведро через HAProxy на экземпляр EC2 и в конечной точке REST для ведра.

Когда возвращается сообщение об ошибке 403, прокси модифицирует тело ответа ответа с использованием нового embedded Lua interpreter, добавив это перед тегом <Error>.

<?xml-stylesheet type="text/xsl" href="/error.xsl"?>\n 

Файл /error.xsl публично читаемым, и использует браузер на стороне XSLT для визуализации довольно ошибочный ответ.

Прокси также вводит несколько дополнительных тегов в xml, <ProxyTime> и <ProxyHTTPCode> для использования в выводе.Результирующий XML выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="/error.xsl"?> 
<Error><ProxyTime>2015-10-13T17:36:01Z</ProxyTime><ProxyHTTPCode>403</ProxyHTTPCode><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>9D3E05D20C1BD6AC</RequestId><HostId>WvdkvIRIDMjfa/1Oi3DGVOTR0hABCDEFGHIJKLMNOPQRSTUVWXYZ+B8thZahg7W/I/ExAmPlEAQ=</HostId></Error> 

Тогда я изменить результат, показанный пользователю с XSL тестов, чтобы определить, какая ошибка состояние S3 забросила:

<xsl:if test="//Code = 'AccessDenied'"> 
    <p>It seems we may have provided you with a link to a resource to which you do not have access, or a resource which does not exist, or that our internal security mechanisms were unable to reach consensus on your authorization to view it.</p> 
</xsl:if> 

И конечный результат выглядит следующим образом:

browser screenshot example of this behavior

выше является общим «Доступ запрещен», потому что никакие учетные данные не были поставлены. Вот пример истекшей подписи.

screenshot of expired signature

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

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

+0

спасибо за этот тщательный ответ. Мне потребуется некоторое время, чтобы реализовать и проверить его; это, безусловно, полезно, и я проголосовал тем временем. –

+0

Отлично, спасибо. Я имел в виду написать сообщение в блоге об этом, включая источник Lua и конфигурацию haproxy, необходимые, чтобы это произошло. Я верну это в свой список и скоро включу ссылку. –

+0

Исходный код - файл XSL и сценарий Lua для HAProxy - https://gist.github.com/sqlbot/ce5388fd452eeb302dfd –

Смежные вопросы