I need to write an OpenID client for a new platform (some funny flavour of server-side javascript) and I am trying to understand the authentication sequence. I've been reading the Ruby implementation and writing tests the types of requests / responses that generates.
The initial request is on the form:
this.getBeginUrl = function(options){
if(!options) throw("getBeginUrl requires an options hash of the form: {return_to_path:'/path/to/return?something', base:'http://server.name'}")
if(!options.return_to_path) throw("must supply return_to_path");
if(!options.base) throw ("must supply base url");
var params = {
'assoc_handle':getAssocHandle(),
'ax.mode':'fetch_request',
'claimed_id':'http://specs.openid.net/auth/2.0/identifier_select',
'identity':'http://specs.openid.net/auth/2.0/identifier_select',
'mode':'checkid_setup',
'ns':'http://specs.openid.net/auth/2.0',
'ns.ax':'http://openid.net/srv/ax/1.0',
'ns.sreg':'http://openid.net/extensions/sreg/1.1',
'realm':options.base,
'return_to':options.base + options.return_to_path + '&open_id_complete=1' // Assuming the return-to url has a ? in it
}
if(options.required) params['sreg.required'] = options.required;
var result = [];
for(var e in params) result.push([escape('openid.'+e)] +"=" +escape(params[e]));
return openid_url + '?' + result.join('&'); // Assuming the openid url didn't have a ? in it already
}
So my question is about how to create this assoc_handle
field and how to verify what comes back from the openid server. And something about nonces.
The response when I send this request is of the form:
'openid.op_endpoint':'https://login.launchpad.net/+openid',
'openid.signed':'assoc_handle,claimed_id,identity,invalidate_handle,mode,ns,ns.sreg,op_endpoint,response_nonce,return_to,signed,sreg.nickname',
'openid.sig':'HMeqwtQ8vG4aNOvRFVSnuOfWv30=',
'openid.response_nonce':'2010-09-29T10:50:31Z3nPoQ3',
'open_id_complete':'1',
'openid.claimed_id':'https://login.launchpad.net/+id/ref466F',
'foo':'bar',
'openid.assoc_handle':'{HMAC-SHA1}{4ca319f7}{+KiTxQ==}',
'openid.sreg.nickname':'michaelforrest',
'openid.ns':'http://specs.openid.net/auth/2.0',
'openid.identity':'https://login.launchpad.net/+id/ref466F',
'openid.ns.sreg':'http://openid.net/extensions/sreg/1.1',
'openid.mode':'id_res',
'openid.invalidate_handle':'foo',
'openid.return_to':'http://localhost:9000/ep/openid/?foo=bar&open_id_complete=1',
So I guess I need to understand how to verify that this response came from the original request before saving contents of the nickname field (which is all I'm really interested in verifying) somewhere.