Как создать предварительно подписанный URL-адрес Amazon S3 для тщеславного домена, используя amazon sdk? - PullRequest
4 голосов
/ 07 марта 2012

У меня есть корзина s3 с именем foo.example.com, все CNAMEd правильно.

Я переключаюсь на последнюю версию AWS .net SDK.

Я хочу создать предварительно подписанный URL, например:

http://foo.example.com/myfile.txt?s3_params_here

Обратите внимание на тщеславие cname.

У меня есть:

string bucketName = "foo.example.com";

AmazonS3Client s3Client = new AmazonS3Client("bar", "xxx",
    new AmazonS3Config
    {
        ServiceURL = bucketName, 
        CommunicationProtocol = Protocol.HTTP
    });


string key = "myfile.txt";


GetPreSignedUrlRequest request = new GetPreSignedUrlRequest()
.WithBucketName(bucketName)
.WithKey(key)
.WithExpires(DateTime.Now.AddMinutes(5))
.WithProtocol(Protocol.HTTP);

string url = s3Client.GetPreSignedURL(request);

URL, который я получаю, выглядит примерно так:

http://foo.example.com.foo.example.com/myfile.txt?AWSAccessKeyId=bar&Expires=1331069777&Signature=234KoUUvfE1nCcs2vLj9RQUhqF8%3D

Что явно не так.

Я пробовал разные варианты с ServiceURL, именем корзины и т. Д., Но, похоже, ничего не работает.

Я не могу найти хорошую документацию - как это правильно сделать?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 16 марта 2012

presignedURL возвращает объект URL после подписания запроса.Я использовал то же самое, и> у меня нет реальных проблем, но есть некоторые вещи, на которые следует обратить внимание:

  1. Убедитесь, что URL объекта, который вы рассматриваете, не имеет '//', это может быть легкопроизойдет, если> вы начинаете путь к хранилищу, начинающийся с «/», вы бы сохранили объект в пути, например> https: ///x/y/z/abc.png, ключ для такого ресурса - x/y/z/abc.png> а не /x/y/z/abc.png

  2. Если вышеупомянутое гарантировано, то из возвращаемого объекта URL получите запроспараметры> из объекта URL url.getQuery () вернет параметры запроса, которые содержат> информацию о подписи, просто добавьте суффикс к исходному awsURL, и все должно работать> с любыми проблемами кодирования.

Надеюсь, это поможет ..

По сути, вам нужно использовать url.getQuery для возвращенного объекта url, а не просто прикреплять его к концу корзины.

https://forums.aws.amazon.com/thread.jspa?threadID=70521

0 голосов
/ 07 марта 2012

Обновление [обходной путь]

Тем временем я разрешил противоречивые результаты моих тестов, которые проистекают из несистематического тестирования и манипуляций с URL.Следующий обходной путь помогает мне (т. Е. Проверен и воспроизводим), просто исходя из вашего решения:

string bucketName = "foo.example.com";

// [...]

GetPreSignedUrlRequest request = new GetPreSignedUrlRequest()
    .WithBucketName(bucketName)
    .WithKey(key)
    .WithExpires(DateTime.Now.AddMinutes(32))
    .WithProtocol(Protocol.HTTP);

Теперь это дает ошибочный URL с дублированным доменным именем, то есть http://foo.example.com.foo.example.com/myfile.txt?[...]

Дубликат может быть просто удален, например:

string url = s3Client.GetPreSignedURL(request);

// KLUDGE: remove duplicate domain name.
url = url.Replace(bucketName + "." + bucketName, bucketName);

Это дает мне правильный рабочий предварительно подписанный URL (т.е. http://foo.example.com/myfile.txt?[...]), обходя обнаруженное ограничениеотносительно желаемого подхода, описанного ниже.

Обоснование

Управление сгенерированным URL-адресом выглядит так странно, но это не влияет на аутентификацию строки запроса в соответствии с тем, как создаются эти подписи,см. Альтернатива аутентификации запроса строки запроса , где вы найдете псевдограмму , которая иллюстрирует метод аутентификации запроса строки запроса :

StringToSign = HTTP-VERB + "\n" +
    Content-MD5 + "\n" +
    Content-Type + "\n" +
    Expires + "\n" +
    CanonicalizedAmzHeaders +
    CanonicalizedResource;    

То естьдоменное имя вообще не используется для создания подписи, а только информация о самом ресурсе;section Пример Query String Request Authentication прямо под ссылочным фрагментом псевдограммы иллюстрирует это фактическим ресурсом.

Assessment

Я не знаю, существует ли ещенедоразумение с нашей стороны, или это может быть просто ошибка в AWS SDK для .NET , см., например, Почему мой предварительно подписанный запрос S3 недействителен, когда я устанавливаю переопределение заголовка ответа, содержащее«+»? для связанной ошибки, исправленной также с помощью аналогичного обходного пути, который, тем не менее, был исправлен;соответственно, его, вероятно, следует передать на форумы AWS и / или каналы поддержки, чтобы получить соответствующий ответ или решение.

Удачи!


Желаемый ответ [дисфункциональный]

Обработка S3 CNAME подразумевает имя корзины уже, поэтому все, что вам нужно сделать, это удалить имя корзины из GetPreSignedUrlRequest, то есть оно должно выглядеть так:

GetPreSignedUrlRequest request = new GetPreSignedUrlRequest()
    .WithKey(key)
    .WithExpires(DateTime.Now.AddMinutes(5))
    .WithProtocol(Protocol.HTTP);

I 'Я проверил это с моим ведром, и оно работает, как и ожидалось, вот так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...