我一直在学习如何通过使用开源 Eucalyptus 来使用 Amazon S3 API。到目前为止,我已经能够成功使用 REST,但现在我也想使用 SOAP。我似乎无法为我的请求生成正确的签名。该服务给我一个 403 Forbidden 错误:
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 指向 Amazon 的常规 S3 服务器。我还有两种不同的方法在我的 create_signature 函数中创建签名。我通过简单地注释掉第二个来在一个和另一个之间交换。两者似乎都不起作用。我的问题是我做错了什么?
SOAP 身份验证:http ://docs.aws.amazon.com/AmazonS3/latest/dev/SOAPAuthentication.html
SUDS-Jurko 文档:https ://bitbucket.org/jurko/suds/overview
编辑:我意识到我忘记包含一个示例,说明出于调试目的而打印的时间戳和签名。
2014-12-05T00:27:41.001Z
0h8vxE2+k10tetXZQJxXNnNUjjw=
编辑 2:另外,我知道 download_file 函数不会下载文件 :) 我仍处于测试/调试阶段
编辑 3:我知道 REST 更好用,至少根据亚马逊的说法。(我个人认为 REST 也更好。)我也已经知道 SOAP 已被 Amazon 弃用。但是,无论如何我都想走这条路,所以请帮我一个忙,不要浪费我的时间与弃用的链接。我向您保证,在编写此 SOAP 代码时,我已经清楚地意识到了弃用。事实上,我发布的其中一个链接在其页面顶部打印了弃用通知。但是,如果您有证据表明 Walrus 完全放弃了 SOAP,或者他们停止了 SOAP 部分的工作,我希望看到类似的情况。但请不要告诉我亚马逊已弃用 SOAP。