Разрешен только один механизм авторизации; только параметр запроса X-Amz-Algorithm..?

Я пытаюсь отправить запрос PUT на назначенный URL-адрес amazonS3. Мой запрос, кажется, называется дважды, даже если у меня есть только один запрос PUT. Первый запрос возвращает 200 OK, второй возвращает 400 Bad Request.

Вот мой код:

var req = {
    method: 'PUT',
    url: presignedUrl,
    headers: {
        'Content-Type': 'text/csv'
    },
    data: <some file in base64 format>
};

$http(req).success(function(result) {
    console.log('SUCCESS!');
}).error(function(error) {
    console.log('FAILED!', error);
});

Ошибка 400 Bad Request более подробно:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
   <Code>InvalidArgument</Code>
   <Message>Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified</Message>
   <ArgumentName>Authorization</ArgumentName>
   <ArgumentValue>Bearer someToken</ArgumentValue>
   <RequestId>someRequestId</RequestId>
   <HostId>someHostId</HostId>
</Error>

Я не понимаю, почему он возвращает 400? и Какое обходное решение?

Ответ 1

Возможно, ваш клиент отправляет исходный запрос, который использует заголовок авторизации, на который отвечает 302. Ответ включает заголовок Location, который имеет параметр Signature. Проблема заключается в том, что заголовки исходного запроса копируются в последующий запрос перенаправления, так что он содержит как авторизацию, так и подпись. Если вы удалите авторизацию с последующего запроса, вам будет хорошо.

Это произошло со мной, но в среде Java/HttpClient. Я могу предоставить подробную информацию о решении на Java, но, к сожалению, не для AngularJS.

Ответ 2

Я знаю, что это может быть слишком поздно, чтобы ответить, но, как сказал @mlohbihler, причиной этой ошибки для меня был заголовок авторизации, отправленный http-перехватчиком, который у меня был в Angular. По сути, я должным образом не отфильтровал домен AWS S3, чтобы избежать автоматического получения заголовка авторизации JWT.

Ответ 3

Кроме того, 400 "недопустимый аргумент" может появиться в результате неправильных конфигурационных/учетных данных для вашего S3:: Presigner, который назначает URL-адрес для начала. Как только вы закончите 400, вы можете столкнуться с 501 "не реализованным" ответом, как я. Удалось решить проблему, указав заголовок Content-Length (указанный здесь как необходимый заголовок). Надеюсь, что это поможет @arjuncc, он решил мою проблему почтальона при тестировании загрузки изображений s3 с назначенным URL-адресом.

Ответ 4

Для Google: если вы отправляете подписанный (подпись v4) запрос S3 через Cloudfront, а для параметра "Ограничить доступ к корзине" установлено значение "Да" в настройках источника Cloudfront, Cloudfront добавит заголовок авторизации к вашему запросу, и вы получите эту ошибку. Поскольку вы уже подписали свой запрос, вы должны иметь возможность отключить этот параметр и не жертвовать какой-либо защитой.