Thursday, November 08, 2012

Javascript API for OpenID

Too long ago I wrote about an Javascript API for openid: all those NASCARs

To repeat the main points:

Sites currently have no easy way to detect support for openid
The site can detect support for openid like so:

   if (window.openid) { don't show the nascar }
The DOM level API that allows the site to query the preferred identity provider looks like this:
   window.openid.getPreferredOpenidProvider(callback);
In a world of oauth2 and openid connect this could be generalized to:
https://openid.net/specs/openid-connect-standard-1_0.html#rf_prep
    var parameters = {};
    parameters.response_type="id_token";
    parameters.client_id="https://server.example.com/seminar/callback.html";
    parameters.request = "eyJhbGciOiJSUzI1NiIsIng1dSI6Imh0dHBzOlwvXC9nYWJ1bm9taS5uZXRcL3NlbWluYXJcL3JzYV9wdWJsaWNfa2V5LnBlbSJ9.ewoJInJlc3BvbnNlX3R5cGUiOiAiaWRfdG9rZW4iLAoJInNjb3BlIjogIm9wZW5pZCIsCgkiY2xpZW50X2lkIjogImh0dHBzOi8vZ2FidW5vbWkubmV0L3NlbWluYXIvY2FsbGJhY2suaHRtbCIsCgkicG9saWN5X3VybCI6ICJodHRwczovL2dhYnVub21pLm5ldC9zZW1pbmFyL3BvbGljeS5odG1sIiwKCSJ1c2VyaW5mbyI6IHsKCQkiY2xhaW1zIjogewoJCQkibmFtZSI6IG51bGwsCgkJCSJlbWFpbCI6IG51bGwsCgkJCSJwaWN0dXJlIjogbnVsbAoJCX0KCX0sCgkicmVnaXN0cmF0aW9uIjogewoJCSJhcHBsaWNhdGlvbl9uYW1lIjogIlNhbXBsZSBTZW1pbmFyIiwKCQkibG9nb191cmwiOiAiaHR0cHM6Ly9nYWJ1bm9taS5uZXQvc2VtaW5hci9sb2dvLnBuZyIsCgkJIng1MDlfdXJsIjogImh0dHBzOi8vZ2FidW5vbWkubmV0L3NlbWluYXIvcnNhX3B1YmxpY19rZXkucGVtIgoJfQp9Cg.Faytuhwb2W4CWVz2-10umSieh-bqR7QXqU0bNF39u_D0mGoBD4e3X2b4jZNqPvPADSnQhlBGSJu189iFM5bwFzchnO-quCpj7T2CK_-wkrpL5LUn_WHYMmYlFadmb-a1p-TEo7exU9azMS9cT70-kHNqmTaJziZyiAMoJ0Q4TtyTt1Xbkknc_CQRug3ilNv3bEXSlOlva3HUOY7jQIbYMB3jDL3QxS1wbVYNAjOxCxCDmiNAUJA-BkYe6Tpyj-DUs57IM4wQSp64sqim8RqirJJfFb4bCbNTkC3G8sYfN2_1-qEDpOnWW7N3gjl174TWHbnzVLAZGg_rZm58-wHOLw";
    parameters.state="509b9cafd3119";
    parameters.nonce="509b9cafd34fd";

    window.openid.connect(parameters, oc_callback);
The callback
oc_callback
would be called with one parameter.
function oc_callback(resp) {
  // resp contains a signed then encrypted id_token in jw-* format
  // https://tools.ietf.org/html/draft-ietf-jose-json-web-encryption
  // https://tools.ietf.org/html/draft-ietf-jose-json-web-signature
  // state and nonce are inside the resp parameter too
  // need a private key to decrypt it so forward it to my own validation endpoint
  $.post("validate.php", { resp: resp },
   function(id_token) {
     alert("returned id_token: " + id_token);
   }); 
}
The general idea is: put all http request parameters which are defined in openid connect into the request object. Put all the http respones parameters into the response object.

I think we need an Javascript API for identity that is supported by browsers. BrowserID/Persona and AccountChooser do something in this direction but not enough.