Daily Archives: December 16, 2009

OpenSocial Widgets – Validating Signed Requests

It is fun when things move quickly. On Monday morning while reading Twitter on my inbound commute, I saw a tweet from Martin Dougiamas about Moodle 2.0 design being different than Moodle 1.0 since things are very different in 2009 than in 2003. He saw things like Ning, etc as part of the mix these days. Back in 2003 things were much simpler so Moodle 1.x could be much simpler.
So I thought to myself, “If Martin is thinking about Ning – maybe I should take a look at it…”. I asked a few friends if they knew anything about Ning. It turns out Michael Korkuska knows some folks at Ning – so I asked Michael if Ning is interested in education. He said there was some interest in education (I was sending E-Mail to Michael Monday night while driving home).
So on the last 40 minutes of my commute Monday night, I idly wondered if there was a way to plug learning tools into Ning using IMS Basic LTI (my obsession).
Tuesday morning, I figured I would work through the Ning developer documentation and make a Ning App. So I started to look at Ning Apps. Woah! Ning Apps are OpenSocial apps. Well that *is* pretty cool excuse to learn OpenSocial coding. Sure it is Javascript, but they give you little pre-provisioned APIs to so stuff like set and get preferences (kind of like SCORM). And they tell you if the current user is the Owner of the widget or just a viewer of the widget. Cool! This will be easy – I was “almost done” before I even started.
Then I realized that this is all Javascript and as such there is zero security. Crap! People can run the whole thing in a Javascript debugger and call any API they like – grrr.
But then I found signed requests and how to validate requests – and in Python even! We are back in business:
http://wiki.opensocial.org/index.php?title=Introduction_To_Signed_Requests
http://wiki.opensocial.org/index.php?title=Validating_Signed_Requests
Oh yes… And then you can preload the data talking server to server to do this in parallel – and make these preloads signed.
http://wiki.opensocial.org/index.php?title=Remote_Data_Requests
Oh and one more thing – it uses OAuth. It does use a public/private key signing pattern instead of shared secret – but hey, it works and has some cool potential for simpler bootstrapping than shared secret. (And it is Tueday lunch time – about 24 hours since I saw Martin’s Tweet).
Going forward – I think that I cannot build an OpenSocial Widget that directly implements IMS Basic LTI because JavaScript is a GIANT security hole that I think is unsolvable (I asked Noah if it could be solved and he said “no” and I never question Noah on matters of breaking JavaScript security).
But I think I can make a *lovely* little App Engine Application that exports a Widget out one end and connects to IMS Basic LTI out the other end seamlessly. While it would be nice to do it inside the widget completely, it appears that here is a *LOT* of variation between OpenSocial containers and that both the spec and vendor level of support is a moving target, the safest bet is to use as little of the OpenSocial API as one can get away with and do as much as possible in our own server to maximize interoperability and the ability to put in vendor-specific hacks as needed. With that in mind, a simple and elegant approach is pretty obvious and will take a few days of hacking to build. Of course I don’t have those days right now since I want to write two books over the break – perhaps this will be an independent study next semester :).
I will end thinking, “what a difference 24 hours can make” when you have people who help you come up with new ideas and people who can help you think. To reward you for reading this rambling tome this far, here is a screen shot of IMS Basic LTI inside of Ning:
.
This is not real code yet – but it does send the signed form to the tool with the auto-submit within the OpenSocial widget. Here is source code
http://www.dr-chuck.com/ning/bltihack.xml
Please do not laugh too much – because I stopped in mid-hack to work on final exams for SI502 and SI539. I stopped once I realized that my in-widget approach was pointless and that a server would need to be involved.