尝试在 Pyramid oauth 提供程序中生成请求令牌时出现无效签名错误
我正在尝试在 Pyramid 应用程序中使用 oauth2
生成请求令牌,以控制对我正在开发的 API 的访问。我一直试图验证我的消费者密钥和秘密工作 这个示例< /a>.在 Pyramid request_token 端点上,我有以下内容:(
@view_config(route_name = "api_request_token", request_method = "GET")
def api_request_token(request):
auth_header = {}
if ('Authorization' in request.headers):
auth_header = {'Authorization': request.headers['Authorization']}
req = oauth2.Request.from_request(
request.method,
request.url,
headers = auth_header,
query_string = request.query_string)
try:
oauth_server.verify_request(req, ConsumerKeySecret.getByConsumerKey(request.params.get('oauth_consumer_key')), None)
except oauth2.Error, e:
print e
except KeyError, e:
print e
except Exception, e:
print e
ConsumerKeySecret.getByConsumerKey
是一个 SQLAlchemy 模型类方法,用于设置 key
和 secret
的实例变量给定密钥
。)
在消费者方面,再次按照前面提到的博客文章,我正在执行以下操作:
def build_request(url, method='GET'):
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth2.generate_nonce(),
'oauth_timestamp': int(time.time()),
'oauth_signature_method': 'HMAC-SHA1',
}
consumer = oauth2.Consumer(key='b9085cb942dc427c92dd', secret='1735fd5b090381dcaf57')
params['oauth_consumer_key'] = consumer.key
req = oauth2.Request(method=method, url=url, parameters=params)
signature_method = oauth2.SignatureMethod_HMAC_SHA1()
req.sign_request(signature_method, consumer, None)
return req
request = build_request("http://localhost:6543/api/01/request_token")
u = urllib2.urlopen(request.to_url())
但是,验证失败,并出现以下错误:
签名无效。预期的签名基字符串: GET&http%3A%2F%2Flocalhost%3A6543%2Fapi%2F01%2Frequest_token&oauth_body_hash%3D2jmj7l5rSw0yVb%252FvlWAYkK%252FYBwk%253D% 26oauth_body_hash%3D2jmj7l5rSw0yVb%252FvlWAYkK%252FYBwk%253D%26oauth_consumer_key%3Db9085cb942dc427c92dd%26oauth_consumer_key%3D b9085cb942dc427c92dd%26oauth_nonce%3D42023151%26oauth_nonce%3D42023151%26oauth_signature_method%3DHMAC-SHA1%26oauth_signature_me thod%3DHMAC-SHA1%26oauth_timestamp%3D1310338562%26oauth_timestamp%3D1310338562%26oauth_version%3D1.0%26oauth_version%3D1.0
然而,我在这里很困惑,因为每个查询字符串参数在“预期”签名中出现两次。可能出了什么问题?
如果这是一个很容易回答的问题,那么我有一个后续问题:一旦我实际验证了请求,如何生成请求令牌? oauth2 库在这一点上的文档有点粗略,大多数示例似乎都是面向实现消费者,而不是创建提供者。
谢谢!
更新回答我自己的问题,给出我认为的答案。从这个oauth2
的错误报告中,它会出现由于我使用的是 GET
,所以包含 oauth_body_hash
参数扰乱了我的签名验证。将其更改为 POST
解决了问题。奇怪的是,鉴于我也在使用这个库进行测试,无论如何都会发生这种情况。
为了回答第二部分,我相信您可以生成任何随机且足够长的密钥/秘密对。我见过人们将一些随机源的 sha1 哈希值分成两个 20 个字符的部分。然后,您可以使用 oauth2.Token
自动创建可在 authorize_token
步骤中使用的 URL。
当然,如果我在这方面有任何错误,请务必告诉我。
I'm trying to generate a request token using oauth2
in a Pyramid application for controlling access to an API I'm developing. I'm stuck trying to verify my consumer key and secret working from this example. On the Pyramid request_token endpoint I have the following:
@view_config(route_name = "api_request_token", request_method = "GET")
def api_request_token(request):
auth_header = {}
if ('Authorization' in request.headers):
auth_header = {'Authorization': request.headers['Authorization']}
req = oauth2.Request.from_request(
request.method,
request.url,
headers = auth_header,
query_string = request.query_string)
try:
oauth_server.verify_request(req, ConsumerKeySecret.getByConsumerKey(request.params.get('oauth_consumer_key')), None)
except oauth2.Error, e:
print e
except KeyError, e:
print e
except Exception, e:
print e
(ConsumerKeySecret.getByConsumerKey
is a SQLAlchemy model classmethod that sets instance variables of key
and secret
for the given key
.)
On the consumer side, again following the blog post mentioned earlier, I'm doing the following:
def build_request(url, method='GET'):
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth2.generate_nonce(),
'oauth_timestamp': int(time.time()),
'oauth_signature_method': 'HMAC-SHA1',
}
consumer = oauth2.Consumer(key='b9085cb942dc427c92dd', secret='1735fd5b090381dcaf57')
params['oauth_consumer_key'] = consumer.key
req = oauth2.Request(method=method, url=url, parameters=params)
signature_method = oauth2.SignatureMethod_HMAC_SHA1()
req.sign_request(signature_method, consumer, None)
return req
request = build_request("http://localhost:6543/api/01/request_token")
u = urllib2.urlopen(request.to_url())
The verification fails, however, with the following error:
Invalid signature. Expected signature base string: GET&http%3A%2F%2Flocalhost%3A6543%2Fapi%2F01%2Frequest_token&oauth_body_hash%3D2jmj7l5rSw0yVb%252FvlWAYkK%252FYBwk%253D%26oauth_body_hash%3D2jmj7l5rSw0yVb%252FvlWAYkK%252FYBwk%253D%26oauth_consumer_key%3Db9085cb942dc427c92dd%26oauth_consumer_key%3Db9085cb942dc427c92dd%26oauth_nonce%3D42023151%26oauth_nonce%3D42023151%26oauth_signature_method%3DHMAC-SHA1%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1310338562%26oauth_timestamp%3D1310338562%26oauth_version%3D1.0%26oauth_version%3D1.0
I'm confused here however as each query string parameter appears twice in the "expected" signature. What could be going wrong?
If that's an easy question to answer, I have a follow-up: once I've actually verified the request, how do I generate the request tokens? The oauth2
library is a little sketchy on documentation regarding this point, and most examples out there seem to be geared towards implementing consumers, rather then creating providers as well.
Thanks!
Update Responding to my own question to give what I think is an answer. From this bug report for oauth2
, it would appear that the inclusion of the oauth_body_hash
parameter was messing up my signature verification since I was using GET
. Changing it to POST
fixed the problem. Strange that this would occur anyway given that I'm also testing with this library.
And to answer the second part, I believe you can just generate any key/secret pair that is random and long enough. I've seen people split up sha1 hashes of some random source into two 20 character parts. You can then us oauth2.Token
to automatically create the URL that you can then use in your authorize_token
step.
Of course, if I'm wrong on any of this be sure to let me know.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这听起来和我遇到的问题一模一样,但我找到了一个不同的(可能的)解决方案。
看起来所有查询字符串参数都包含两次,此错误报告中对此进行了描述: https://github.com/simplegeo/python-oauth2/issues/21
剥离查询字符串参数,因为问题描述为我解决了这个问题。
This sounds exactly like a problem I ran into, but I came to a different (possible) solution.
It looks like all the query string parameters are being included twice, which is described in this bug report: https://github.com/simplegeo/python-oauth2/issues/21
Stripping the query string parameters as the issue described fixed it for me.