AWS S3 - Як виправити помилку "Підпис запиту, який ми розрахували, не відповідає підпису"?


90

Я вже більше двох днів шукаю в Інтернеті і, мабуть, переглядаю більшість задокументованих в Інтернеті сценаріїв та обхідних шляхів, але дотепер у мене нічого не працювало.

Я працюю на AWS SDK для PHP V2.8.7, що працює на PHP 5.3.

Я намагаюся підключитися до мого сегмента S3 з таким кодом:

// Create a `Aws` object using a configuration file

        $aws = Aws::factory('config.php');

        // Get the client from the service locator by namespace
        $s3Client = $aws->get('s3');

        $bucket = "xxx";
        $keyname = "xxx";

        try {
            $result = $s3Client->putObject(array(
                'Bucket'        =>      $bucket,
                'Key'           =>      $keyname,
                'Body'          =>      'Hello World!'
            ));
            $file_error = false;
        } catch (Exception $e) {
            $file_error = true;
            echo $e->getMessage();
            die();
        }
        //  

Мій файл config.php такий:

<?php

return array(
    // Bootstrap the configuration file with AWS specific features
    'includes' => array('_aws'),
    'services' => array(
        // All AWS clients extend from 'default_settings'. Here we are
        // overriding 'default_settings' with our default credentials and
        // providing a default region setting.
        'default_settings' => array(
            'params' => array(
                'credentials' => array(
                    'key'    => 'key',
                    'secret' => 'secret'
                )
            )
        )
    )
);

Це спричиняє таку помилку:

Підпис запиту, який ми розрахували, не відповідає підпису, який ви надали. Перевірте свій ключ та спосіб підписання.

Я вже перевіряв свій ключ доступу та секрет принаймні 20 разів, створював нові, використовував різні методи передачі інформації (тобто профіль та включення облікових даних у код), але наразі нічого не працює.


3
Отже, AWS SDK просто реалізує купу прямих викликів API. За допомогою AWS кожен ваш дзвінок приймає ваш приватний ключ (або secretвище) і використовує його для обчислення підпису на основі вашого ключа доступу, поточної позначки часу та безлічі інших факторів. Див. Docs.aws.amazon.com/general/latest/gr/… . Це довго, але, враховуючи те, що вони включають позначку часу, можливо, час у вашому місцевому середовищі закінчився?
Джош Паднік,

Сталося, коли ми передали неправильний розмір ( Content-Length) в метаданих об’єкта. (Довга версія: ми безпосередньо передавали вхідний потік з Java HttpServletRequestклієнту S3 і передавали request.getContentLength()як Content-Lengthчерез метадані; коли сервлет (випадковим чином) отримував фрагментовані запити ( Transfer-Encoding: chunked), getContentLength()повертався -1- що призвело putObjectдо помилки (випадково). Невідомо; але очевидно, що ми винні, бо ми передавали неправильний розмір об’єкта.)
Джанака Бандара,

Джош, час на мої ноутбуки був на годину вихідний (чомусь він був встановлений на московський, а не лондонський час). Дякуємо за допомогу!
Росс Саймондс

Відповіді:


79

Після двох днів налагодження я нарешті виявив проблему ...

Ключ, який я призначав об’єкту, починався з точки, тобто ..\images\ABC.jpg, і це спричинило помилку.

Я хотів би, щоб API надав більш значуще та відповідне повідомлення про помилку, на жаль, я сподіваюся, це допоможе комусь іншому!


У мене був сегмент стану та ключ назад, і це помилка, яку ви отримуєте (підпис не збігається). Wtf тераформ?
Ло-Тан,

14
Провідна коса риса також спричинила цю проблему для мене. Вам потрібен лише шлях / до / файлу, а не / шлях / до / файлу
Грем

3
І для мене це питання були пробіли всередині ключа
Адам

3
На додачу до цього я отримав це повідомлення про помилку, коли +в моєму ключі був знак плюса .
LCC

1
Я отримав це, коли не Content-Type
вказав

34

Я отримую цю помилку з неправильними обліковими даними. Я думаю, що були невидимі символи, коли я вставляв їх оригінально.


3
Я просто натиснув на dobuble, key_hash_lala/key_hash_continuesі він вибрав лише одну частину. На жаль, як важко сказати користувачеві "неправильний пароль, чувак!"?
Ufos

Перший раз у мене виникли проблеми з копіюванням ключа із завантажуваного csv. Щодо другого створеного мною ключа, я просто скопіював його з браузера і не мав жодних проблем
nthaxis

+1 до @nthaxis - копіювання з .csv призвело до помилки - копіювання безпосередньо з браузера, і це спрацьовує
NKCampbell

14

У мене була та ж проблема при спробі скопіювати об’єкт із деякими символами UTF8. Нижче наведено приклад JS:

var s3 = new AWS.S3();

s3.copyObject({
    Bucket: 'somebucket',
    CopySource: 'path/to/Weird_file_name_ðÓpíu.jpg',
    Key: 'destination/key.jpg',
    ACL: 'authenticated-read'
}, cb);

Вирішено шляхом кодування CopySource за допомогою encodeURIComponent()


9

Здається, ця помилка трапляється здебільшого, якщо перед та після вашого секретного ключа залишається пробіл


це допомога повна
містер S Coder

Була така сама проблема. Skype іноді копіює значення порожніми рядками. Просто вставте його в блокнот, а потім скопіюйте без пробілів.
michal-michalak

Так ! Також перевірте, чи є пробіли в інших заголовках.
Ейно Гурдін

6

Насправді в Java я отримав таку ж помилку. Провівши 4 години для її налагодження, я виявив, що проблема полягала в метаданих в об'єктах S3, оскільки було вільне місце під час керування кешем у файлах s3. Це місце було дозволено в 1.6. * версія, але в 1.11. * це заборонено, і, таким чином, виникає помилка невідповідності підпису


Також трапляється, якщо ви передаєте неправильну інформацію Content-Lengthв метаданих
Джанака Бандара,

3

Якщо жодне з інших згаданих рішень не працює для вас, спробуйте використати

aws configure

ця команда відкриє набір опцій із запитом ключів, регіону та формату виводу.

Сподіваюся, це допомагає!


3

Для мене я використовував аксіо і, глухо кажучи, він надсилає заголовок

content-type: application/x-www-form-urlencoded

тож я зміню передати:

content-type: application/octet-stream

а також повинен був додати цей тип вмісту до підпису AWS

const params = {
    Bucket: bucket,
    Key: key,
    Expires: expires,
    ContentType = 'application/octet-stream'
}

const s3 = new AWS.S3()
s3.getSignedUrl('putObject', params)

3

У попередній версії aws-php-sdk, до припинення використання S3Client::factory()методу, вам було дозволено розмістити частину шляху до файлу або, Keyяк це називають у S3Client->putObject()параметрах , на параметрі сегмента. У мене був файловий менеджер у виробничому використанні, використовуючи v2 SDK. Оскільки заводський метод все ще працював, я не переглядав цей модуль після оновлення до ~3.70.0. Сьогодні я витратив більшу частину двох годин на налагодження, чому я почав отримувати цю помилку, і все закінчилося через параметри, які я передавав (які раніше працювали):

$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
    'Bucket' => 'awesomecatpictures/catsinhats',
    'Key' => 'whitecats/white_cat_in_hat1.png',
    'SourceFile' => '/tmp/asdf1234'
]);

Мені довелося перенести catsinhatsчастину шляху відро / ключ до Keyпараметра, наприклад:

$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
    'Bucket' => 'awesomecatpictures',
    'Key' => 'catsinhats/whitecats/white_cat_in_hat1.png',
    'SourceFile' => '/tmp/asdf1234'
]);

Що, на мою думку, відбувається, це те, що Bucketім’я зараз кодується за URL-адресою. Після подальшої перевірки точного повідомлення, яке я отримував від SDK, я виявив таке:

Помилка виконання PutObjectнаhttps://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png

Помилка HTTP AWS: Помилка клієнта: PUT https://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.pngпризвела до403 Forbidden

Це показує, що /я надав для мого Bucketпараметра пройшов urlencode()і зараз %2F.

Принцип роботи підпису досить складний, але проблема зводиться до сегмента, і ключ використовується для генерації зашифрованого підпису. Якщо вони не збігаються точно як на клієнті, що викликає, так і в межах AWS, тоді запит буде відхилено за допомогою 403. Повідомлення про помилку насправді вказує на проблему:

Підпис запиту, який ми розрахували, не відповідає підпису, який ви надали. Перевірте свій ключ та спосіб підписання.

Отже, моя Keyпомилилася, бо моя Bucketпомилилася.


3

У мене була така сама помилка в nodejs. Але додавання signatureVersionконструктора s3 мені допомогло:

const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  signatureVersion: 'v4',
});

Випробував багато речей, перш ніж я натрапив на це! Це була відповідь для мене.
DavidG

2

Я щойно випробував це завантаження зображення на S3 за допомогою AWS SDK із React Native. Виявилося, що це викликано ContentEncodingпараметром.

Видалення цього параметра "виправило" проблему.


2

У мене була та ж проблема. У мене був метод за замовчуванням, PUT встановлений для визначення попередньо підписаної URL-адреси, але намагався виконати GET. Помилка сталася через невідповідність методу.


Це спрацювало для мене. Дієслово HTTP (PUT, POST), що використовується для генерації підписаної URL-адреси, має бути таким самим, як і дієслово, яке використовується під час завантаження з цією URL-адресою.
craigcaulfield

2

У моєму випадку я використовував, s3.getSignedUrl('getObject')коли мені потрібно було використовувати s3.getSignedUrl('putObject')(оскільки я використовую PUT для завантаження свого файлу), саме тому підписи не збігаються.


Врятував мене після довгих годин. Дякую!!
Кісінга

1

У мене була подібна помилка, але для мене вона, здавалося, була спричинена повторним використанням користувача IAM для роботи з S3 у двох різних середовищах Elastic Beanstalk. Я обробив симптом, створивши ідентично дозволеного користувача IAM для кожного середовища, і це призвело до помилки.


1

У моєму випадку я проаналізував URL-адресу S3 на його компоненти.

Наприклад:

Url:    s3://bucket-name/path/to/file

Проаналізовано:

Bucket: bucket-name
Path:   /path/to/file

Маючи частину шляху, що містить провідну '/', помилка запиту.


1

Іншою можливою проблемою може бути те, що метазначення містять символи, що не є US-ASCII. Для мене це допомогло UrlEncode значення при додаванні їх до putRequest:

request.Metadata.Add(AmzMetaPrefix + "artist", HttpUtility.UrlEncode(song.Artist));
request.Metadata.Add(AmzMetaPrefix + "title", HttpUtility.UrlEncode(song.Title));

1

Я вирішив цю проблему, змінивши загальнодоступні дозволи на моєму сегменті AWS s3 та додавши наведену нижче конфігурацію CORS до моїх налаштувань сегмента.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration>
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Докладнішу інформацію див. У документації AWS s3 .


1

Найчастіше це відбувається через неправильний ключ (AWS_SECRET_ACCESS_KEY). Будь ласка, перевірте свій AWS_SECRET_ACCESS_KEY. Сподіваюся, це спрацює ...


1

Я отримав цю помилку під час спроби скопіювати об’єкт. Я виправив це, кодуючи copySource. Це насправді описано в документації до методу:

Параметри: copySource - ім'я вихідного сегмента та ім'я ключа вихідного об'єкта, розділених косою рисою (/). Потрібно закодувати URL-адресу.

CopyObjectRequest objectRequest = CopyObjectRequest.builder()
                .copySource(URLEncoder.encode(bucket + "/" + oldFileKey, "UTF-8"))
                .destinationBucket(bucket)
                .destinationKey(newFileKey)
                .build();

1

У моєму випадку я використовував S3 (верхній регістр) як назву служби під час надсилання запиту за допомогою листоноші в методі авторизації підпису AWS


Ви можете додати більше деталей, де розміщувати знак AWS?
Містер S Кодер,

1

Після налагодження та витрачання багато часу, у моєму випадку проблема полягала в access_key_id та secret_access_key, просто перевірте свої облікові дані або створіть нові, якщо це можливо, і переконайтеся, що ви передаєте ці дані в параметрах.


Коли я прочитав вищезазначену відповідь, я ще раз перевірив свій секретний ключ і зрозумів, що додав / наприкінці.
Ezrqn Kemboi


0

У моєму випадку ім'я відра було помилковим, воно включало першу частину ключа (bucketxxx / keyxxx) - з підписом не було нічого поганого.


0

У моєму випадку (python) це не вдалося, оскільки у мене були ці два рядки коду у файлі, успадковані від старого коду

http.client.HTTPConnection._http_vsn = 10 http.client.HTTPConnection._http_vsn_str = 'HTTP/1.0'


0

Я зіткнувся з цим в образі Docker, з кінцевою точкою, яка не є AWS S3, під час використання останньої awscliверсії, доступної для Debian stretch, тобто версії 1.11.13.

Оновлення до версії CLI 1.16.84 вирішило проблему.

Щоб встановити останню версію CLI із файлом Docker на основі розтяжного образу Debian, замість:

RUN apt-get update
RUN apt-get install -y awscli
RUN aws --version

Використання:

RUN apt-get update
RUN apt-get install -y python-pip
RUN pip install awscli
RUN aws --version

0

Довелося встановлювати

Aws.config.update({
  credentials: Aws::Credentials.new(access_key_id, secret_access_key)
})

раніше з ruby ​​aws sdk v2 (мабуть, щось подібне є і в інших мовах)


0

Я не знаю, чи хтось стикався з цією проблемою під час спроби перевірити виведену URL-адресу у браузері, але якщо ви використовуєте Postmanта намагаєтесь скопіювати згенеровану URL-адресу AWS з RAWвкладки, через уникнення зворотних скісних рисок ви отримаєте вищезазначену помилку .

Скористайтеся Prettyвкладкою, щоб скопіювати та вставити URL-адресу, щоб перевірити, чи справді вона працює.

Нещодавно я стикався з цим питанням, і це рішення вирішило моє питання. Для цілей тестування потрібно перевірити, чи дійсно ви отримуєте дані за допомогою URL-адреси.

Ця відповідь є посиланням на тих, хто намагається згенерувати завантаження, тимчасове посилання з AWS або загалом сформувати URL-адресу з AWS для використання.


0

Проблема в моєму випадку полягала в URL-адресі шлюзу API, який використовувався для налаштування Amplify, що мав додаткову косу риску в кінці ...

Запитана URL-адреса мала вигляд https://....amazonaws.com/myapi//myendpoint. Я видалив зайву скісну риску в конф, і це спрацювало.

Не найвідвертіше повідомлення про помилку в моєму житті.


0

У моєму випадку я дзвонив s3request.promise().then()неправильно, що призвело до двох виконань запиту, коли відбувся лише один дзвінок.

Я маю на увазі, що я переглядав 6 об’єктів, але було зроблено 12 запитів (це можна перевірити, увійшовши в консоль або налагодивши мережу в браузері)

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


0

Виникла ця помилка під час завантаження документа до CloudSearch через Java SDK. Проблема пов’язана із особливим символом у документі, який потрібно завантажити. Помилка "Підпис запиту, який ми розрахували, не відповідає наданому вами підпису. Перевірте свій секретний ключ доступу та спосіб підписання AWS." дуже вводить в оману.


0

генерування нового ключа доступу працювало у мене.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.