Eucalyptus Walrus / Amazon S3 SOAP签名失败

时间:2014-12-05 00:49:32

标签: python soap amazon-web-services amazon-s3 eucalyptus

我一直在学习如何使用开源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。不管怎样,我想沿着这条路走下去,所以请帮我一个忙,不要浪费我的时间来链接到弃用。我向你保证,在编写这个SOAP代码时,我已经很清楚这个弃用了。事实上,我发布的其中一个链接在其页面顶部打印了弃用通知。但是,如果您有证据表明Walrus完全抛弃SOAP或者他们停止在SOAP部分工作,我希望看到类似的东西。但请不要告诉我亚马逊已弃用SOAP。

3 个答案:

答案 0 :(得分:1)

S3 SOAP API不支持&#34; new&#34;功能因此应尽可能使用REST API:

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

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

IIRC最新版本的Eucalyptus不支持带S3的SOAP。

那就是说,签名看起来不错,所以我会检查客户端/服务主机是否有正确的时间,如果差异超过15分钟,则认证失败。

您还可以检查Walrus服务主机上的cloud-error.log,因为可能会有更多有关失败的详细信息。

答案 1 :(得分:0)

从Eucalyptus 4.0.0开始,Eucalyptus不支持S3 for SOAP。

如果您使用的是旧版本的Eucalyptus(4.0之前版本),那么SOAP应该可以使用。但请注意,S3提供的wsdl对于他们自己的服务来说不一定是当前的或准确的。 S3因更改没有版本或wsdl颠簸的API而臭名昭着,特别是因为他们停止更新SOAP API。因此,Walrus可能的响应不符合已发布的WSDL,因为我们的XML是基于我们从S3(通过REST)看到的响应以及SOAP和REST响应分歧而更新的。然而,签名应该是兼容的,所以最坏的情况是你会看到500或400个错误,但不会有403个错误。

我的建议是,如果您真的想学习S3 SOAP API,那么您必须正确使用S3。 Eucalyptus中的S3 SOAP支持是4.0之前的版本,但可能不符合S3 SOAP的当前状态 - 当AWS SDK停止使用SOAP以支持更好的REST支持时,我们不再直接针对S3 SOAP API进行测试,因为那是API向前发展。

答案 2 :(得分:0)

Eucalyptus支持SOAP(参见ZachH关于弃用的评论): https://www.eucalyptus.com/docs/eucalyptus/4.0.2/schemas/aws-apis/s3/index.html

我决定使用python废弃,而我用C#生成了一些工作代码。结果证明C#有更好的SOAP库。