2014-12-05 2 views
0

Я изучаю, как использовать API Amazon S3 с использованием Eucalyptus с открытым исходным кодом. До сих пор мне удалось успешно использовать REST, но теперь я также хотел бы использовать SOAP. Кажется, у меня проблемы с созданием правильной подписи для моего запроса. Сервис дает мне 403 Запретный ошибка:Eucalyptus Walrus/Amazon S3 подпись SOAP не работает

Traceback (most recent call last): 
    File "soap.py", line 31, in <module> 
    r = w.download_file('mybucket', 'test.txt') 
    File "soap.py", line 27, in download_file 
    r = self.client.service.ListAllMyBuckets(self.access_key, timestamp, signature) 
    File "/usr/lib/python2.6/site-packages/suds/client.py", line 521, in __call__ 
    return client.invoke(args, kwargs) 
    File "/usr/lib/python2.6/site-packages/suds/client.py", line 581, in invoke 
    result = self.send(soapenv) 
    File "/usr/lib/python2.6/site-packages/suds/client.py", line 619, in send 
    description=tostr(e), original_soapenv=original_soapenv) 
    File "/usr/lib/python2.6/site-packages/suds/client.py", line 677, in process_reply 
    raise Exception((status, description)) 
Exception: (403, u'Forbidden') 

Мой код на Python 2 и использует библиотеку SUDS-Jurko для отправки запросов SOAP:

from suds.client import Client 

class WalrusSoap: 
    wsdl_url = 'https://s3.amazonaws.com/doc/2006-03-01/AmazonS3.wsdl' 
    server_url = 'https://localhost:8773/services/Walrus' 

    def __init__(self, access_key, secret_key): 
     self.access_key = access_key 
     self.secret_key = secret_key 
     self.client = Client(self.wsdl_url) 
     self.client.wsdl.services[0].setlocation(self.server_url) 
     #print self.client 

    def create_signature(self, operation, timestamp): 
     import base64, hmac, hashlib 
     h = hashlib.sha1(self.secret_key) 
     h.update("AmazonS3" + operation + timestamp) 
     #h = hmac.new(key=self.secret_key, msg="AmazonS3" + operation + timestamp, digestmod=hashlib.sha1) 
     return base64.encodestring(h.digest()).strip() 

    def download_file(self, bucket, filename): 
     from time import gmtime, strftime 
     timestamp = strftime('%Y-%m-%dT%H:%M:%S.001Z', gmtime()) 
     print(timestamp) 
     signature = self.create_signature('ListAllMyBuckets', timestamp) 
     print(signature) 
     r = self.client.service.ListAllMyBuckets(self.access_key, timestamp, signature) 
     return r 

w = WalrusSoap(access_key='MOBSE7FNS6OC5NYC75PG8', secret_key='yxYZmSLCg5Xw6rQVgoIuVLMAx3hZRlxDc0VOJqox') 
r = w.download_file('mybucket', 'test.txt') 
print(r) 

Я изменил конечную точку сервера, так как в противном случае WSDL указывает на обычные серверы S3 на Amazon. У меня также есть два разных способа создания подписи в моей функции create_signature. Я переключался между одним и другим, просто комментируя второй. Ни один из них, похоже, не работает. Мой вопрос в том, что я делаю неправильно?

SOAP Authentication: http://docs.aws.amazon.com/AmazonS3/latest/dev/SOAPAuthentication.html

SUDS-Jurko Документация: https://bitbucket.org/jurko/suds/overview

Edit: я понял, что я забыл включить пример того, что метка времени и подпись печатается для отладки.

2014-12-05T00:27:41.001Z 
0h8vxE2+k10tetXZQJxXNnNUjjw= 

Edit 2: Кроме того, я знаю, что функция download_file не загружает файл :) Я все еще тестирования/отладки фазы

Edit 3: Я знаю, что REST лучше использовать, по крайней мере, согласно Амазонке. (Лично я считаю, что REST также лучше.) Я также уже знаю, что SOAP устарел от Amazon. Однако я хотел бы пойти по этому пути в любом случае, поэтому, пожалуйста, сделайте мне одолжение и не тратьте время на ссылки на усталость. Уверяю вас, что при написании этого SOAP-кода я уже хорошо знал об этом. Фактически, одна из ссылок, которые я разместил, имеет уведомление об устаревании, напечатанное в верхней части страницы. Однако, если у вас есть доказательства того, что Walrus полностью перегружает SOAP или что они перестали работать над частью SOAP, я бы хотел увидеть что-то подобное. Но, пожалуйста, не говорите мне, что Amazon устарела SOAP.

ответ

0

Eucalyptus поддерживает SOAP (см комментарий ZachH по поводу устаревания): https://www.eucalyptus.com/docs/eucalyptus/4.0.2/schemas/aws-apis/s3/index.html

я решил отказаться от использования питона, и я произвел некоторый рабочий код с C# вместо этого. Оказывается, на C# есть лучшие библиотеки SOAP.

1

SOAP-API S3 не поддерживает "новые" черты так REST API следует использовать там, где это возможно:

http://docs.aws.amazon.com/AmazonS3/latest/dev/SOAPAPI3.html

https://forums.aws.amazon.com/message.jspa?messageID=77821

IIRC последние версии Eucalyptus не поддерживают SOAP с S3 ,

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

Вы также можете проверить cloud-error.log на хосте службы Walrus, поскольку там может быть больше информации о сбое.

+0

Я знаю, что время не может быть неправильным, потому что скрипт, который я запускаю для подключения к Walrus, запускается с той же виртуальной машины, на которой размещается Walrus. Как вы могли заметить, server_url указывает на localhost. Я попробовал 'localtime()' вместо 'gmtime()' anyways, чтобы быть уверенным, и безрезультатно. К сожалению, ничего не помогло в cloud-error.log. Спасибо, что проверил мою подпись. –

+0

Также есть ли у вас доказательства того, что Walrus не поддерживает SOAP? –

0

Eucalyptus не поддерживает SOAP для S3 от версии Eucalyptus 4.0.0.

Если вы используете более старую версию Eucalyptus (до 4.0), то SOAP должен работать. Обратите внимание, однако, что wsdl, предоставляемый S3, не обязательно является актуальным или точным даже для их собственной службы. S3 известен тем, что изменил API без ошибок версии или wsdl, особенно потому, что они перестали обновлять SOAP API.Таким образом, есть вероятные ответы от Walrus, которые не соответствуют опубликованному WSDL, потому что наш XML был обновлен на основе ответов, которые мы видим из S3 (через REST), и ответы SOAP и REST расходились. Подписи должны быть совместимы, однако в худшем случае вы увидите 500 или 400 ошибок, но не 403 ответа.

Моя рекомендация - если вы действительно хотите изучить S3 SOAP API, вам нужно будет использовать S3. Поддержка S3 SOAP в Eucalyptus существует до 4.0, но может не соответствовать текущему состоянию S3 SOAP - мы прекратили тестирование против S3 SOAP API напрямую, когда AWS SDK перестали использовать SOAP в пользу лучшей поддержки REST, поскольку это было API продвигается вперед.

+0

От того, как вы говорите, я предполагаю, что вы работали над проектом. Если это так, спасибо за предоставление доказательств. В будущем, где бы я искал журнал изменений для Эвкалипта? –

+0

@KevinTindall Да, я возглавляю хранилище Eucalyptus. Я должен был сделать это более ясным. Если у вас есть еще вопросы, вы также можете найти нас на IRC-freenode в # eucalyptus-devel – ZachH

+0

@KevinTindall, в отношении журнала изменений это [здесь] (https://www.eucalyptus.com/docs/eucalyptus/4.0. 2/index.html # общий/release_notes.html). Похоже, что удаление S3 SOAP поддержки не было включено, это проблема, и я буду работать над тем, чтобы зафиксировать это в документе. – ZachH