Как реализовать клиент OpenID с нуля? - PullRequest
3 голосов
/ 29 сентября 2010

Мне нужно написать 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. И что-то про одноразовые номера.

Ответ, когда я отправляю этот запрос, имеет форму:

'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',

Так что, я думаю, мне нужно понять, как проверить, что этот ответ пришел от исходного запроса, прежде чем сохранять содержимое поля псевдонима (и это все, что мне действительно интересно проверить).

1 Ответ

5 голосов
/ 29 сентября 2010

Во-первых, прочитайте спецификацию . Во-вторых, прочитайте спецификацию . Сделайте это еще несколько раз, чтобы у вас было смутное представление о том, как это работает, затем попробуйте реализовать его, а затем снова внимательно прочитайте спецификацию, чтобы убедиться, что вы ничего не забыли.

Я говорю это не потому, что просто хочу отправить вас к руководству, а потому, что если вы пропустите одну маленькую деталь, вы можете внести критическую уязвимость в вашу библиотеку.

В любом случае, assoc_handle устанавливается поставщиком, а не клиентом. Раздел 8 спецификации описывает, как получить ручку. В качестве альтернативы вы можете просто не заботиться о дескрипторе связывания и использовать режим без сохранения состояния (потому что это проще).

В режиме без сохранения состояния для подтверждения ответа вы просто отправляете запрос обратно с параметрами, содержащимися в поле openid.signed, плюс поле openid.sig и openid.mode, установленное на check_authentication.

И, как вы и просили, есть кое-что о: они уникальны и начинаются с полной метки времени в utc, в формате iso 8601.

Кстати, вы не заинтересованы в проверке поля sreg.nickname. Вы хотите проверить claimed_id. sreg.nickname даже не должен присутствовать в ответе, даже если вы запрашиваете его.

Тем не менее, очень важно прочитать спецификацию. Просто заставить его работать не достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...