签署SimpleDB请求



我正在尝试使用Python对亚马逊的SimpleDB服务进行API调用。举个例子,我用的是最简单的请求,ListDomains。然而,无论我如何尝试,响应总是"我们计算的请求签名与您提供的签名不匹配"。

这是我正在签名的字符串(按照这里的文档):

GET
https://sdb.amazonaws.com/
/
AWSAccessKeyId=<redacted>&Action=ListDomains&SignatureMethod=HmacSHA1&SignatureVersion=2&Timestamp=2011-04-19T18%3A50%3A43&Version=2009-04-15

我用下面的代码签名:

import base64,hashlib,hmac,time                                            
# Sign the request                                                                           
signature = hmac.new(                                                                        
    key=AWS_SECRET_ACCESS_KEY,                                                               
    msg=string_to_sign,                                                                      
    digestmod=hashlib.sha1).digest()                                                         
# Base64 encode the signature                                                                
signature = base64.encodestring( signature )

我已经尝试过HmacSHA256和HmacSHA1。似乎什么都不管用。我做错了什么?

一个关键问题是你必须正确地对所有HTTP参数值进行URL编码。

下面的文档已经从SimpleDB文档中消失了,但是可以在SQS文档中找到,并且仍然与SimpleDB非常相关:

不要对任何URL进行编码rfc3986规定的非保留字符定义。

这些无保留字符是A-Z,A-z, 0-9,连字符-,下划线_),句号(。),和波浪(~)。

%编码所有其他字符与%XY,其中X和Y是十六进制字符0-9和大写字母A-F.

%编码扩展UTF-8格式为%XY%ZA

的字符

%将空格字符编码为%20(而不是+,作为通用编码)计划做)。

您将注意到,在Roger链接的python-simpledb模块中,它们在形成请求时遵循以下规则:

def escape(s):
  return urllib.quote(s, safe='-_~')
def urlencode(d):
  if isinstance(d, dict):
    d = d.iteritems()
  return '&'.join(['%s=%s' % (escape(k), escape(v)) for k, v in d])

我不想重新发明轮子-有几个python simpledb库,如;

  • https://github.com/sixapart/python-simpledb
  • http://code.google.com/p/boto/wiki/SimpleDbIntro

如果没有别的,他们的签名代码应该澄清你的错误是什么,但说真的,使用现有的维护API,它会让你的生活更容易。

相关内容

  • 没有找到相关文章

最新更新