我正在对基于SAML的单一登录(SSO)的开源implementations之一进行反向工程

当SSO成功时,我从idp(identity provider)获得POST,并调用以下函数:

router.post('/acs/:idp?', function (req, res, next) {
  console.log('got a post from idp');
    var _idp, _sp;
    if (req.params.idp === 'onelogin') {
      console.log('the idp is onelogin or vidm in this case');
        _idp = oneLoginIdP;
        _sp = olsp;
    } else {
        _idp = idp;
        _sp = sp;
    }
    _sp.parseLoginResponse(_idp, 'post', req, function (parseResult) {
      console.log('trying to parse assertion to see if it is valid');
      console.log('name id'+parseResult.extract.nameid);

        if (parseResult.extract.nameid) {
            res.render('login', {
                title: 'Processing',
                isSSOLogin: true,
                email: parseResult.extract.nameid
            });
        } else {
            req.flash('info', 'Unexpected error');
            res.redirect('/login');
        }
    });
});


现在,我们可以看到该函数在serverivceprovider对象(_sp)上调用了一个名为parseLoginResponse的函数。 parseLoginResponse如下所示:

ServiceProvider.prototype.parseLoginResponse = function parseLoginResponse(idp, binding, req, parseCallback) {
        return this.abstractBindingParser({
            parserFormat:
            [
            {
                localName: 'StatusCode',
                attributes: ['Value']
            },
            {
                localName: 'Conditions',
                attributes: ['NotBefore', 'NotOnOrAfter']
            },
            'Audience',
            'Issuer',
            'NameID',
            {
                localName: 'Signature',
                extractEntireBody: true
            },
            {
                localName: {
                    tag: 'Attribute',
                    key: 'Name'
                },
                valueTag: 'AttributeValue'
            }
          ],
            checkSignature: this.entityMeta.isWantAssertionsSigned(),
            from: idp,
            supportBindings: ['post'],
            parserType: 'SAMLResponse',
            actionType: 'login'
        }, binding, req, idp.entityMeta, parseCallback);
    };


我的三个具体问题:


How is the callback working for parseCallback method.
I am new to javascript so I don't get at which exact line parseCallback is receiving it's argument i.e parseResult?
我可以在parseCallback中成功打印以下行:

console.log('name id'+parseResult.extract.nameid);



但是我找不到一种方法来打印包含notbefore和notonorafter时间的属性。 How can I print attributes section of parseResult or the commplete parseResult argument?

最佳答案

方法this.abstractBindingParser();接受5个参数。最后-parseCallback功能。因此,您可以在this.abstractBindingParser()内部传递此函数。它会在this.abstractBindingParser()内部内部调用;

您不知道内部将如何调用它,将哪些参数传递给parseCallback。您可以参考所用系统的文档,也可以使用魔术变量arguments。将console.log(arguments);放在console.log('name id' + parseResult.extract.nameid);之后

09-25 19:44