我需要为新平台编写一个OpenID客户端(服务器端javascript的一些有趣的味道),我正在尝试理解身份验证序列。我一直在阅读Ruby实现并编写测试生成的请求/响应的类型。
初始请求在表格中:
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
}
所以我的问题是关于如何创建这个assoc_handle
字段以及如何验证openid服务器返回的内容。关于nonces的事情。
发送此请求时的响应格式为:
'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',
所以我想我需要了解如何验证这个响应来自原始请求,然后保存昵称字段的内容(这是我真正感兴趣的是验证)。
答案 0 :(得分:5)
首先,阅读specification。其次,阅读specification。再多做一次,这样你就会对它是如何工作有一个模糊的想法,然后尝试实现它,然后再仔细阅读规范,这样你就可以确定你没有忘记任何事情。
我不是这么说的,因为我只是想给你发一本手册,但是如果你错过了一个小细节,你可能会在你的图书馆中引入一个关键漏洞。
无论如何,assoc_handle
由提供者设置,而不是由客户端设置。规范的第8节描述了如何获得句柄。或者,你根本不关心assoc句柄,并使用无状态模式(因为它更简单)。
在无状态模式下,为了验证响应,您只需发回请求,其中包含openid.signed
字段中包含的参数,加上openid.sig
字段,openid.mode
设置为{ {1}}。
根据您的要求,这里有一些内容:它们是独一无二的,以utc的完整时间戳开始,采用iso 8601格式。
顺便说一句,您对验证check_authentication
字段不感兴趣。您想验证sreg.nickname
。即使您提出要求,claimed_id
甚至不必出现在回复中。
但是,阅读规范非常重要。仅仅让它发挥作用是不够的。