【问题标题】:Eucalyptus Walrus/Amazon S3 SOAP signature is failingEucalyptus Walrus/Amazon S3 SOAP 签名失败
【发布时间】:2015-01-01 01:13:18
【问题描述】:

我一直在学习如何通过使用开源 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。

【问题讨论】:

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


    【解决方案1】:

    S3 SOAP API 不支持“新”功能,因此应尽可能使用 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,因为那里可能有更多关于故障的详细信息。

    【讨论】:

    • 我知道时间不会错,因为我正在运行以连接到 Walrus 的脚本是从托管 Walrus 的同一虚拟机上运行的。您可能已经注意到 server_url 指向 localhost。我确实尝试了localtime() 而不是gmtime() 无论如何只是为了确定,但无济于事。不幸的是,cloud-error.log 中没有任何帮助。感谢您检查我的签名。
    • 你有任何证据表明Walrus不支持SOAP吗?
    【解决方案2】:

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

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

    我的建议是,如果您真的想学习 S3 SOAP API,则必须正确使用 S3。 Eucalyptus 中的 S3 SOAP 支持在 4.0 之前就已存在,但可能与 S3 SOAP 的当前状态不兼容——当 AWS 开发工具包停止使用 SOAP 以支持更好的 REST 支持时,我们直接停止了针对 S3 SOAP API 的测试,因为那是API 向前发展。

    【讨论】:

    • 从你说话的方式来看,我假设你已经参与了这个项目。如果是这样,谢谢你提供证据。将来我会在哪里寻找 Eucalyptus 的更新日志?
    • @KevinTindall 是的,我是 Eucalyptus 存储的负责人。我应该更清楚地说明这一点。如果您还有更多问题,还可以在#eucalyptus-devel 的 freenode IRC 上找到我们
    • @KevinTindall,关于更新日志,它是here。看起来 S3 SOAP 支持删除不包括在内,这是一个问题,我会努力在文档中解决这个问题。
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-19
      • 2016-04-27
      • 2018-12-27
      • 1970-01-01
      • 2016-02-08
      • 2021-10-26
      相关资源
      最近更新 更多