尝试在 Pyramid oauth 提供程序中生成请求令牌时出现无效签名错误

发布于 2024-11-19 08:51:37 字数 3095 浏览 4 评论 0原文

我正在尝试在 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 模型类方法,用于设置 keysecret 的实例变量给定密钥。)

在消费者方面,再次按照前面提到的博客文章,我正在执行以下操作:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心凉怎暖 2024-11-26 08:51:37

这听起来和我遇到的问题一模一样,但我找到了一个不同的(可能的)解决方案。

看起来所有查询字符串参数都包含两次,此错误报告中对此进行了描述: 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文