Table Of Contents

Validating Signed Requests from OpenSocial ApplicationsΒΆ

Here we want to show how to validate OAuth signed requests from an OpenSocial container, using the example of Orkut.

To validate requests from Orkut, the following function can be defined outside your controller class:

import base64
import hashlib
import urllib

from opensocial import oauth
from Crypto.PublicKey import RSA
from Crypto.Util import number

def validate_signed_orkut():
       # Construct a RSA.pubkey object
       exponent = 65537
       public_key_str = """0x\
00b1e057678343866db89d7dec2518\
99261bf2f5e0d95f5d868f81d600c9\
a101c9e6da20606290228308551ed3\
acf9921421dcd01ef1de35dd3275cd\
4983c7be0be325ce8dfc3af6860f7a\
b0bf32742cd9fb2fcd1cd1756bbc40\
0b743f73acefb45d26694caf4f26b9\
765b9f65665245524de957e8c547c3\
58781fdfb68ec056d1"""

       public_key_long = long(public_key_str, 16)
       public_key = RSA.construct((public_key_long, exponent))

       # Apply the public key to the signature from the remote host
       sig = base64.decodestring(urllib.unquote(request.params["oauth_signature"]))

       remote_hash = public_key.encrypt(sig, '')[0][-20:]

       # Rebuild the message hash locally
       oauth_request = oauth.OAuthRequest(http_method=request.method,
                                          http_url=request.browser_url, # request.url for TG2
                                          parameters=request.params.mixed())
       message = '&'.join((oauth.escape(oauth_request.get_normalized_http_method()),
                           oauth.escape(oauth_request.get_normalized_http_url()),
                           oauth.escape(oauth_request.get_normalized_parameters()),))
       local_hash = hashlib.sha1(message).digest()

       # Verify that the locally-built value matches the value from the remote server.
       if local_hash != remote_hash:
           raise Exception('Incorrect user signature!')

Then, in a controller method where you expect a signed request, just code like this:

@expose('json')
def foo(self, **params):
    validate_signed_orkut()
    return {'success' : True}

Reference: http://code.google.com/apis/opensocial/articles/appengine-0.8.html#signing