Working with OAuth

OAuth Client

Sausalito's OAuth module and OAuth Commons module simplify the interaction with service providers that support OAuth. OAuth is an open protocol to allow secure API authorization in a standard method. Service providers like Google, Doodle and Twitter allow to access their APIs through OAuth. By using these APIs, user data can be accessed. For example calendar entries (Google) and participated polls (Doodle).

Sausalito provides a template project that illustrates OAuth access to Doodle, Google and Twitter. The template can be created by executing the following command:

sausalito create template -n oauth

This template uses the OAuth Commons module that simplifies the handling with certain OAuth service providers even more. The usage of the Commons module is recommended because no OAuth knowledge is needed.

To access a service provider not supported by the OAuth Commons module or if you wanna have full control over the OAuth process, you need to use the OAuth Standard module explained below.

Short Introduction to OAuth

As a first step, the consumer (application using the OAuth module) asks a service provider (like Google) for a request token. The service provider issues this token and sends it back to the consumer (in case the consumer provided correct authentication data). In step 2, the consumer redirects the user to the authorization page of the service provider. After successful authorization the service provider redirects the user back to the consumer's callback page. Afterwards the original request token is authorized and the consumer can exchange the request token for an access token (step 3). Finally (step 4) the consumer can access protected resources with the access token.

Depending on the service provider the consumer might be able to directly exchange a request token for an access token without prior user authorization. Of course, such an access token doesn't allow to access user specific resources.

A more detailed introduction is provided at OAuth.net (especially part II).

Create a Service Provider Structure

Before interacting with a service provider, you need to define a structure that specifies the service provider and authorization data (examples can be found at Service Provider Structures). The service provider Google is used for the example below. It is recommended to store the structure as a variable in one of your handler or library modules because it is used as a parameter in all OAuth function calls.

Example:

declare variable $def:service-provider as schema-element (oa:service-provider) :=
  validate {
  <oa:service-provider realm="www.google.com"> 
    ...
  </oa:service-provider> };

Interaction with the Service Provider

Before accessing user data from the service provider, an valid access token must be received from the service provider by following the steps described in the introduction. Depending on the service provider, additional parameters may be required during this process. Please take a look at the service provider's documentation for further information.

To use the OAuth functions, the OAuth module must be imported:

import module namespace oauth="http://www.28msec.com/modules/oauth/client";

Additionally the OAuth schema must be imported to access XML elements in the OAuth namespace and validate the function parameters:

import schema namespace oa="http://www.28msec.com/schemas/oauth/client";
Request Token

In our example we want to query the Google calendars from a user. To get a request token, Google needs an additional parameter that specifies the Google services (the scope).

Example to get the request token:

let $parameters :=
	<oa:parameters>
		<oa:parameter name="scope">
			http://www.google.com/calendar/feeds/
		</oa:parameter>
	</oa:parameters>
let $callback-url := "http://localhost:8080/default/callback"
let $request-token-pair := oauth:request-token(
				$def:service-provider, 
				$callback-url, 
				validate { $parameters }, 
				()
			   )

The response from oauth:request-token contains the token key ($request-token-pair/oa:token/text()) and the token secret ($request-token-pair/oa:token-secret/text()). Depending on your service provider, additional parameters may be returned.

User Authorization

In the last step you retrieved an unauthorized request token. It gets authorized by the following code:

return 
(
	scs:set($request-token-pair),
	oauth:user-authorization($def:service-provider, $request-token-pair, ())
)

Your user is redirected to the authorization page of the service provider. After the user logged in and granted access, he is redirected to the callback URL specified in step 1. Before redirecting your user to the authorization page, make your request token persistent (e.g. by storing it in a cookie).

Access Token

The service provider redirected the user to your site (callback page) and submitted two additional parameters: oauth_token and oauth_verifier. These two parameters and the request token secret are used to exchange the original request token for an access token:

let $oauth-token := http:getParameters("oauth_token")[1] 
(: compare oauth_token with the one in the cookie... :)
let $oauth-verifier := http:getParameters("oauth_verifier")[1]
let $request-token-pair := validate { scs:get() }
let $access-token-pair:= oauth:access-token(
				$def:service-provider, 
				$request-token-pair, 
				$oauth-verifier
                               )
return
(
	scs:set($access-token-pair),
	...
)

The response from oauth:access-token contains the access token and access token secret. These are needed to access protected resources. Depending on your service provider additional parameters may be included. You may store the access token and access token secret in a cookie for easier access later on. Remark: for security reasons, you may want to compare the OAuth token received from the service provider with the one saved in the cookie.

Protected Ressource

As mentioned at the beginning, we want to get a list of the user's calendars:

let $access-token-pair := validate { scs:get() }
let $http-request :=
	validate {
	<oa:http-request>
		<oa:target-url>
			http://www.google.com/calendar/feeds/default/allcalendars/full
		</oa:target-url>
	</oa:http-request>
	}
let $http-response := oauth:protected-resource(
				$def:service-provider, 
				$http-request, 
				$access-token-pair
		      )
return $http-response/oa:payload/node()

Remarks

Some service providers may still interact according the OAuth Spec 1.0. The behaviour described in this example uses OAuth spec 1.0a. You can “simulate” the outdated spec by passing the additional parameter oauth_callback to oauth:user-authorization. The value of the parameter oauth_callback is the callback URL used in step 1.

OAuth Server

Sausalito's OAuth Server module simplifies building an own service provider that serves protected resources.

Sausalito provides a template project that illustrates how to build an OAuth server. The template can be created by executing the following command:

sausalito create template -n oauthserver
 
 
 
working_with_oauth.txt · Last modified: 2010/04/26 14:08 (external edit)
 
Recent changes RSS feed Creative Commons License Valid XHTML 1.0 Valid CSS
backlinks | direct link: [working_with_oauth]