Skip to content

Instantly share code, notes, and snippets.

@carlos8f
Created October 25, 2011 20:22
Show Gist options
  • Select an option

  • Save carlos8f/1314123 to your computer and use it in GitHub Desktop.

Select an option

Save carlos8f/1314123 to your computer and use it in GitHub Desktop.
FreedomConnector Single Sign-on documentation

FreedomConnector Single Sign-on

This document describes how a 3rd party site (consumer) can authenticate users using their FreedomConnector (provider) account. FreedomWorks uses this technique to implement single sign-on between sub-sites, but it may also be usable to non-FreedomWorks sites as well.

Client-side Single Sign-on

Terra Eclipse has developed a simple JSONP-based service, which can expose a limited amount of profile data to 3rd party sites via javascript.

The consumer embeds a javascript on their site, passing a callback name of their choice:

<script type="text/javascript" src="http://connect.freedomworks.org/session.json?callback=myCallback"></script>

The response, if the user is logged in, will look like:

HTTP/1.1 200 OK
Content-Type: text/javascript; charset=utf-8

myCallback({"uid":61,"name":"carlos8f","picture":"http:\/\/connect.freedomworks.org\/picture\/61?size=tiny","first":"Carlos","last":"Rodriguez"});

The consumer implements a javascript callback to receive the user data and treat the user as authenticated. If the user is not logged in, the response becomes:

HTTP/1.1 200 OK
Content-Type: text/javascript; charset=utf-8

myCallback({"uid":0,"name":"Anonymous"});

The consumer may then choose to redirect the user to log in via the provider site, as described below.

Server-side Single Sign-on

The server-side API is a modified OAuth workflow. It depends on the consumer receiving a challenge code, generating a cryptographic signature from it using a private key, which is then validated by the provider server.

Terra Eclipse generates a key pair for the consumer. Example:

client_id: f634c36fc3dac73ce03829f52ac35e38
private key: 0816c4b121b9065a81c1eb23defdadc6

Consumer server, upon receiving an authentication request, generates a cryptographic nonce (random string). Every nonce must be unique. The server responds with a 302 redirect, containing the client_id, redirect_uri, and nonce (parameters must be url-encoded, they are shown in plaintext here for reference):

Location: http://connect.freedomworks.org/oauth/authenticate
  ?client_id = f634c36fc3dac73ce03829f52ac35e38
  &redirect_uri = http://my.server/process_return
  &nonce = 1f75abde356ded945228f2b66203e82a

The consumer server stores the nonce in the session for later reference.

At the provider site, the user is authenticated. This might happen immediately if a session is active, or the user may have to log in or register. Upon completion, the user is redirected back to the redirect_uri. The consumer server is passed a challenge code as a GET variable:

Location: http://my.server/process_return
  ?code = AvEjvyT2oMi8jCdZmPfk5ivyQJI=

The consumer must then create a server-side HTTP request to the provider, containing a cryptographic signature of the code generated with the nonce and private key.

GET http://connect.freedomworks.org/oauth/access_token
  ?code = AvEjvyT2oMi8jCdZmPfk5ivyQJI=
  &nonce = 1f75abde356ded945228f2b66203e82a
  &signature = fIDhp5ibCLP4+L6jYnAsuuNbmD4=

The signature is generated with these steps:

  1. Concatenate the nonce with the private key.
  2. Generate a raw HMAC-SHA1 (binary) of the code, using the result of step 1 as the key.
  3. Base64-encode the result.

The provider server will send 200 OK response if the signature is correct:

HTTP/1.1 200 OK
Content-Type: text/javascript; charset=utf-8

{"access_token":"RtrDxq+\/vguM3PoHWPCY3HgKCP8=","account":{"uid":"61","name":"carlos8f","mail":"[email protected]",...}}

The response is a JSON object containing an access token and an account object. The user's UID, user name, first + last name, email address, and zip code can all be extracted from this object.

The access_token can be used to fetch the user data at a later time:

GET http://connect.freedomworks.org/api/me
  ?access_token = RtrDxq+/vguM3PoHWPCY3HgKCP8=

The response will be the same as above, only without the access_token.

Upon a validation error, the server will respond:

HTTP/1.1 400 Bad Request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment