Invalid signature error when trying to generate request token in Pyramid oauth provider
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.开发者_JS百科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.
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.
精彩评论