Ошибка 403 REST API Amazon S3 С#

Я пытаюсь заставить некоторый код работать для извлечения файла из S3 с использованием REST API через С#. Я видел, как другие люди делают подобные вещи, но по какой-то причине я продолжаю получать ошибку 403. Я пытался сделать то же самое с AWS SDK для .Net, и это работает, поэтому я предполагаю, что именно так я создаю заголовок авторизации.

Кто-нибудь может пролить свет на это, пожалуйста?

string awsAccessId = "***";
string awsSecretKey = "***";
string bucketName = "thebucket";

string httpDate = DateTime.Now.ToString("ddd, dd MMM yyyy HH:mm:ss +0000\n");
                string canonicalString = "GET\n"
                                        + "\n"
                                        + "\n"
                                        + "x-amz-date:" + httpDate + "\n"
                                        + "/" + bucketName + "/readme.txt";

                // now encode the canonical string
                Encoding ae = new UTF8Encoding();
                // create a hashing object
                HMACSHA1 signature = new HMACSHA1();
                // secretId is the hash key
                signature.Key = ae.GetBytes(awsSecretKey);
                byte[] bytes = ae.GetBytes(canonicalString);
                byte[] moreBytes = signature.ComputeHash(bytes);
                // convert the hash byte array into a base64 encoding
                string encodedCanonical = Convert.ToBase64String(moreBytes);

                // Send the request
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://" + bucketName +".s3.amazonaws.com/readme.txt");
                request.Headers.Add("x-amz-date", httpDate);
                request.Headers.Add("Authorization", "AWS " + awsAccessId + ":" + encodedCanonical);
                request.Method = "GET";

                // Get the response
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Console.WriteLine(response.StatusCode);
                Console.Read();

person MarkJ    schedule 30.10.2013    source источник
comment
Почему бы не использовать SDK, если он работает?   -  person Oskar Kjellin    schedule 30.10.2013
comment
Я надеюсь поместить это в задачу сценария SSIS   -  person MarkJ    schedule 31.10.2013


Ответы (2)


Я проверил ваш код, он работает! вам просто нужен дополнительный \n плюс изменение http на https, и все готово.

 string stringToConvert = "GET\n"
                          + "\n"
                          + "\n"
                          + "\n"
                          + "x-amz-date:" + timeStamp + "\n"  
                          + "/" + bucketName + "/" + FileName;

Amazon Rest API не имеет хорошей документации, отсутствие примеров заставляет всех переходить на SDK.

person Celso Dias Catarino Neto    schedule 02.10.2014

Я не знаю, является ли это единственной проблемой, но похоже, что это определенная проблема:

+ "x-amz-date:" + httpDate + "\n"

x-amz-date — это заголовок, который заменяет заголовок Date: в самом HTTP-запросе, но в строке для подписи вы просто ставите дату без «x-amz-date:» или чего-либо перед ней, согласно примерам:

GET\n
\n
\n
Tue, 27 Mar 2007 19:36:42 +0000\n
/johnsmith/photos/puppy.jpg

http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationRequestCanonicalization

Для запроса может быть сгенерирована только одна правильная подпись. S3 сгенерирует эту подпись и сравнит ее с той, которую вы отправили, поэтому в строке для подписи нет ни единого байта места для ошибки.

person Michael - sqlbot    schedule 31.10.2013
comment
Спасибо за ваше предложение. Я сделал модификацию, но, к сожалению, она все еще не работает. - person MarkJ; 31.10.2013
comment
Сообщение 403 возвращает ошибку, которая дает вам строку для подписи и говорит вам, что подпись не совпадает, или нет? Что говорит ошибка? (в теле ответа) - person Michael - sqlbot; 31.10.2013
comment
В сообщении об ошибке говорится, что подпись не соответствует: ‹Error›‹Code›SignatureDoesNotMatch‹/Code›‹Message›Рассчитанная нами подпись запроса не соответствует предоставленной вами подписи. Проверьте свой ключ и метод подписи.‹/Message› - person MarkJ; 31.10.2013