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