0

I wrote a simple oauth provider and consumer using the pecl oauth package. Everything goes well until I attempt to get an access token, at which point I get a signature mismatch error. The oauth consumer attempts to contact the provider using the oauth->getauthorizedtoken in the following way:

$res = mysql_query("SELECT * FROM request_tokens WHERE oauth_token = '".mysql_real_escape_string($token)."'");
$requestToken = mysql_fetch_assoc($res);

$oauth->setToken($token, $requestToken['oauth_token_secret']);
$authToken = $oauth->getAccessToken("http://dev.myserver.com/~testbranch/?m=oauthMod&act=authorize", NULL, $verifier);

When this fails it spits out debug info with a signature like:

3qBMmue4Q+j8Dm4/9VSTl6y0TR8=

On the provider side, the consumer and token are verified and then it fails with a signature mismatch even though the signature it calculates is:

3qBMmue4Q%2Bj8Dm4%2F9VSTl6y0TR8%3D

Which is obviously an url escaped version of the exact same signature. Is this a bug or am I blatantly missing something?

Nielsvh
  • 1,151
  • 1
  • 18
  • 31
  • How do you calculate the signature? Why is it urlencoded? – hakre Apr 10 '12 at 16:04
  • As far as I can tell, pecl's oauth and oauth provider both generate the signature. The one generated on the provider side follows the http://oauth.net/core/1.0a/#encoding_parameters specification. It would seem that oath package does not encode the parameter? – Nielsvh Apr 10 '12 at 17:02
  • Well the first one is not encoded, the second one is. However: `rawurlencode('3qBMmue4Q+j8Dm4/9VSTl6y0TR8=') === '3qBMmue4Q%2Bj8Dm4%2F9VSTl6y0TR8%3D';` – hakre Apr 10 '12 at 17:06
  • I got those backwards, the class OAuthProvider does not seem to follow specifications and the OAuth class does. – Nielsvh Apr 10 '12 at 17:50
  • Then look for [`rawurldecode`](http://php.net/rawurldecode). And make visible inside your example code, where you run into the problem specifically. – hakre Apr 10 '12 at 17:51
  • "Fixed" issue for now by checking in my OAuthExcpetion handler whether the signatures do actually match using oauth_urlencode and continuing on if they do. – Nielsvh Apr 10 '12 at 19:14

2 Answers2

0

As noted in my question, the two signatures are identical with the exception that one is the url encoded. This is not part of the specification and is not documented, but there it is. My final solution checks both for signature matches and url encoded signature matches. This is not ideal, as there are chances for false matches, but there is little I can do without rewriting the entire algorithm from scratch.

Nielsvh
  • 1,151
  • 1
  • 18
  • 31
0

OAuthProvider::$signature is the decoded value of oauth_signature from the consumer's request and not the OAuthProvider-calculated signature. So printing the Authorization header received by OAuthProvider will include oauth_signature="3qBMmue4Q%2Bj8Dm4%2F9VSTl6y0TR8%3D" while OAuthProvider::$signature will show 3qBMmue4Q+j8Dm4/9VSTl6y0TR8=.

If your work around is getting the oauth_signature from the Authorization header (or equivalent) and comparing it to an encoded OAuthProvider::$signature ... those will always match!

The issue I had with OAuthProvider throwing a signature mismatch exception was the result of not providing the endpoint URI to OAuthProvider::checkOAuthRequest(). The documentation indicates that this is optional, but it needed to be included since it's part of the signature base string.