OAuth for gadgets

35 views
Skip to first unread message

Brian Eaton

unread,
Apr 25, 2008, 7:56:36 PM4/25/08
to opensocial-an...@googlegroups.com, oa...@googlegroups.com
Google is implementing a feature we call the OAuth Proxy to enable
Gadgets (such as on iGoogle or OpenSocial containers) to access OAuth
protected resources. Next week we will provide some details on how to
use this with the recently announced iGoogle sandbox. However we have
also contributed the code for this feature to the Apache open-source
project called Shindig which provides a reference implementation of
the Gadget spec.

We hope that members of the OAuth community will try to create gadgets
that access OAuth resources, and give us feedback on the OAuth Proxy,
especially at this weekend's OAuth hackathon. Wei Tu from Google will
be there if you want to give us feedback, or feel free to respond to
this E-mail. You could even contribute extensions to the OAuth Proxy
in the Shindig project.

We have provided some documentation below on how to setup a Shindig
instance with this feature, and we have also provided a sample gadgets
that accesses the Google Contacts API which has alpha support of
OAuth.

How can I see a demo?

If you'd like to see how the OAuth proxy lets widgets use OAuth, try
this (it requires that you have a Gmail account with some E-mail
addresses in your contact list):

Download, build, and run the example Shindig server. (The Shindig
build is being refactored right now, so you should check out an older,
stable version of Shindig)

1. svn co -r 648154
http://svn.apache.org/repos/asf/incubator/shindig/trunk shindig
2. download http://dirk.balfanz.googlepages.com/oauth.json
3. replace shindig/config/oauth.json with the one you just downloaded
4. cd shindig/java/gadgets
5. mvn jetty:run-war

Walk through the demo.

1. Direct your browser to
http://localhost:8080/gadgets/files/samplecontainer/samplecontainer.html
2. Change the gadget URL to http://dirk.balfanz.googlepages.com/contacts.xml
3. Hit reset, twice. (Bug in sample container)
4. Click the "Personalize this gadget" link.
5. You are redirected to the service provider. Grant access.
6. Close the popup window.
7. Click the "I've approved access" link in the OAuth gadget.
8. You should see your contacts for your Google account.
9. If you want to repeat this demo with a different Google Account,
just login to that account, and repeat steps 1-8 above but after step
change the viewer/owner to some other value.


You can also test Shindig against the sample OAuth service provider
from oauth.net:

Download the sample service provider code:

1. svn co http://oauth.googlecode.com/svn/code/java oauth
2. cd oauth
3. mvn install
4. cd example/oauth-provider/
5. mvn jetty:run-war

Walk through the demo.

1. Direct your browser to
http://localhost:8080/gadgets/files/samplecontainer/samplecontainer.html
2. Change the gadget URL to
http://localhost:8080/gadgets/files/samplecontainer/examples/oauth.xml
3. Hit reset, twice. (Bug in sample container)
4. Click the "Personalize this gadget" link.
5. You are redirected to the service provider. Enter "OAuth is
supercool" on the service provider page.
6. Close the popup window.
7. Click the "I've approved access" link in the OAuth gadget.
8. You should see "OAuth is supercool" in the gadget.


How can I write my own gadget?

Writing a gadget that uses OAuth is easy.

Start with a copy of the Shindig oauth.xml gadget or the contacts
gadget at http://dirk.balfanz.googlepages.com/contacts.xml.

Host your new gadget somewhere. You can get an account at
www.googlepages.com, or put your gadget in the
shindig/javascript/samplecontainer/examples in a local copy of
Shindig.

Get a consumer key and secret for your gadget. The oauth.json file at
http://dirk.balfanz.googlepages.com/oauth.json has test keys for the
oauth.net demo service provider and the Google contacts API. (The
consumer_secret (which is an RSA signing key) in oauth.json for the
contacts gadget is for test purposes only and will be revoked sometime
in the future, so at some point you'll need to use
https://www.google.com/accounts/ManageDomains to register your own.)

Edit the shindig/config/oauth.json file to add your gadget URL, the
nickname for your service provider (e.g. "demo" or "google"), and your
consumer key and secret.

Modify the <Require feature="oauth"> section in the gadget source to
point to the three OAuth service provider URLs. (This should be
automated once we add support for OAuth discovery and service
providers support it.)

Modify the fetchData() function in the gadget to specify the URL of
the data you want to fetch and your OAUTH_SERVICE nickname. (This has
to match what you put in the oauth.json file.)

Restart Shindig to pick up any changes to oauth.json, put the URL of
your gadget into the sample container, and start working on your
gadget.


The Shindig support for OAuth is still experimental. This is alpha
code. The details of the gadget APIs are going to change. The error
messages aren't very helpful. If something doesn't work, first check
that oauth.json and your gadget XML file are properly formatted. If
you still can't get things working, send a note to
shind...@apache.org and we'll try to help you out.

End-to-end protocol flow

The players:

* gadget/opensocial container (e.g. MySpace/Hi5/iGoogle/otherse) that
authenticates users

* the gadget (e.g. some gadget that can do cool stuff with your contacts)

* gadget rendering server (e.g. Shindig) that can make gadgets run.

* service provider (e.g. gmail) that can provide user data for the gadget

The goal:
The key thing here is that a user has two accounts, one on the
container page, and another on the service provider. Those accounts
need to be linked, somehow, in order for the gadget to display the
user's data. OAuth is the protocol we use to connect the accounts and
get the data from the service provider to the gadget.

The flow:

1. Through some unspecified process the container, the gadget
author, and the service provider all shake hands to decide on a
consumer key and consumer secret for the gadget. Think of this as a
username and password for the gadget. Eventually we want this to
happen automatically, but at first this will probably happen with a
nod and a handshake. Along with the consumer key and consumer secret
the service provider hands out some URL endpoints for use during the
OAuth protocol dance.
2. User adds the gadget to their container home page.
3. Container issues the gadget a gadget security token that acts as
a temporary authentication token for the user. This is how the gadget
rendering server knows which gadget and which user are making the
request.
4. Gadget sends a request to the gadget rendering server proxy
asking that the proxy fetch the user's data from the service provider.
The request includes the security token and a request to do OAuth.
5. The gadget rendering server sends a 'request token' message to
the service provider request token endpoint. The request token
message is signed with the consumer key and secret, to identify the
container and gadget. The service provider returns an OAuth request
token (which is an opaque blob as far as the container and gadget
server are concerned.)
6. The gadget rendering server returns an approval URL (including
the request token) to the gadget. The approval URL is hosted by the
service provider.
7. Gadget pops up a window to the approval URL on the service provider.
8. The service provider requires the user to login, if they aren't
logged in already.
9. The service provider asks the user to grant permission for the
container and gadget to view the user's data. (e.g. "Can gadget X on
iGoogle view your gmail contacts?")
10. The user says OK. They may be redirected back to the container
at this point, or the window may just close. (Both approaches are
permitted by the OAuth spec, and both can work.)
11. The gadget sends another request to the gadget server asking
that the proxy fetch the user's data from the service provider.
12. This time the proxy sends an 'access token' message to the
service provider access token endpoint. The access token message
includes the request token.
13. The service provider looks up the request token, sees that the
user approved access, and returns an OAuth access token and access
token secret.
14. The gadget server sends a request to the service provider
resource access endpoint, signing the request with the access token
and the access token secret.
15. The service provider looks up the access token and sees that the
user has granted permission for the gadget to view their data.
16. The service provider returns the data to the proxy.
17. The proxy returns the data to the gadget.
18. The gadget does something cool with the data.


On subsequent requests this all goes much more quickly. The gadget
server can look up the access token and use it immediately. If the
user later decides they don't want the gadget to see their data any
longer, they can ask the service provider to revoke access.


Cheers,
Brian

Chakradhar Nanga

unread,
Apr 26, 2008, 11:27:00 AM4/26/08
to opensocial-an...@googlegroups.com, oa...@googlegroups.com
Hi Brian,

Thank you for the detailed notes on how this whole process works - it's
very helpful.

One of key requirements here is that a gadget's consumer_key,
consumer_secret and the gadget_url be made available to the
gadget/OpenSocial containers i.e. the config data that goes into
shindig/config/oauth.json in the steps described below.

It seems that the process of communicating this info. will probably vary
from one container to another.

How do you foresee this working for iGoogle? If I'm an iGoogle gadget
developer, how do I go about communicating my consumer secret in a
secure manner to iGoogle? This also implies that I trust the iGoogle
container with the shared secret from my Service Provider?

Thanks
Chak

Dirk Balfanz

unread,
Apr 29, 2008, 2:08:51 AM4/29/08
to opensocial-an...@googlegroups.com, oa...@googlegroups.com
Well, there are actually two different options here:

(1) The gadget is the OAuth consumer, and you're right that in this
case the key/secret information contained in the oauth.json file
somehow has to be communicated through a different channel to the
gadget container.

(2) The container itself is the OAuth consumer, and uses _its_ keys
and secrets to make requests (see
http://groups.google.com/group/oauth/browse_thread/thread/4d92022416452851).
In this case, there is actually no need at all to send consumer keys
and secrets to the container.

We haven't decided yet whether we will support (1), or (2), or both -
or how we would implement the part in (1) where gadget developers
would have to tell us their consumer keys and secrets. Does this make
sense?

Dirk.

Dirk Balfanz

unread,
May 30, 2008, 8:09:19 PM5/30/08
to oa...@googlegroups.com, opensocial-an...@googlegroups.com
We have now integrated OAuth support for gadgets into the Orkut sandbox.

Here is a public webpage with a sample walkthrough of an OAuth gadget:

https://sites.google.com/site/ericsachs/demoproxy

Dirk.

Reply all
Reply to author
Forward
0 new messages