From 46d8ad99ac83945ac56c26f81c1f188b2d56bd0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20Poikaj=C3=A4rvi?= Date: Mon, 25 May 2015 19:24:09 +0300 Subject: [PATCH 1/3] Generate logout request that should work with WSO2, but it doesn't --- lib/passport-saml/saml.js | 41 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/passport-saml/saml.js b/lib/passport-saml/saml.js index 86d2748e..f0fd4fd7 100644 --- a/lib/passport-saml/saml.js +++ b/lib/passport-saml/saml.js @@ -186,6 +186,36 @@ SAML.prototype.generateLogoutRequest = function (req) { return xmlbuilder.create(request).end(); }; +SAML.prototype.generateSaml2pLogoutRequest = function (req) { + var id = "_" + this.generateUniqueID(); + var instant = this.generateInstant(); + + var request = { + 'saml2p:LogoutRequest' : { + '@xmlns:saml2p': 'urn:oasis:names:tc:SAML:2.0:protocol', + '@Reason': 'urn:oasis:names:tc:SAML:2.0:logout:user', + '@ID': id, + '@Version': '2.0', + '@IssueInstant': instant, + '@Destination': this.options.logoutUrl, + 'saml2:Issuer' : { + '@xmlns:saml2': 'urn:oasis:names:tc:SAML:2.0:assertion', + '#text': this.options.issuer + }, + 'saml2:NameID' : { + '@xmlns:saml2': 'urn:oasis:names:tc:SAML:2.0:assertion', + '@Format': req.user.nameIDFormat, + '#text': req.user.nameID + }, + 'saml2p:SessionIndex' : { + '#text': req.user.sessionIndex + } + } + }; + + return xmlbuilder.create(request).end(); +} + SAML.prototype.generateLogoutResponse = function (req, logoutRequest) { var id = "_" + this.generateUniqueID(); var instant = this.generateInstant(); @@ -294,8 +324,10 @@ SAML.prototype.getAuthorizeUrl = function (req, callback) { }; SAML.prototype.getLogoutUrl = function(req, callback) { - var request = this.generateLogoutRequest(req); + //var request = this.generateLogoutRequest(req); + var request = this.generateSaml2pLogoutRequest(req); var operation = 'logout'; + console.log(request); this.requestToUrl(request, null, operation, this.getAdditionalParams(req, operation), callback); }; @@ -527,6 +559,13 @@ SAML.prototype.processValidlySignedAssertion = function(xml, inResponseTo, callb profile.issuer = issuer[0]; } + var authnStatement = assertion.AuthnStatement; + if (authnStatement) { + if (authnStatement[0].$ && authnStatement[0].$.SessionIndex) { + profile.sessionIndex = authnStatement[0].$.SessionIndex; + } + } + var subject = assertion.Subject; if (subject) { var nameID = subject[0].NameID; From 3311afd9bcaf56d7e28890b97b297df5e51158d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20Poikaj=C3=A4rvi?= Date: Tue, 26 May 2015 11:55:18 +0300 Subject: [PATCH 2/3] SessionIndex works when added to current request --- lib/passport-saml/saml.js | 39 +++++++-------------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/lib/passport-saml/saml.js b/lib/passport-saml/saml.js index f0fd4fd7..13c4f9f9 100644 --- a/lib/passport-saml/saml.js +++ b/lib/passport-saml/saml.js @@ -183,38 +183,15 @@ SAML.prototype.generateLogoutRequest = function (req) { } }; - return xmlbuilder.create(request).end(); -}; - -SAML.prototype.generateSaml2pLogoutRequest = function (req) { - var id = "_" + this.generateUniqueID(); - var instant = this.generateInstant(); - - var request = { - 'saml2p:LogoutRequest' : { + if (req.user.sessionIndex) { + request['samlp:LogoutRequest']['saml2p:SessionIndex'] = { '@xmlns:saml2p': 'urn:oasis:names:tc:SAML:2.0:protocol', - '@Reason': 'urn:oasis:names:tc:SAML:2.0:logout:user', - '@ID': id, - '@Version': '2.0', - '@IssueInstant': instant, - '@Destination': this.options.logoutUrl, - 'saml2:Issuer' : { - '@xmlns:saml2': 'urn:oasis:names:tc:SAML:2.0:assertion', - '#text': this.options.issuer - }, - 'saml2:NameID' : { - '@xmlns:saml2': 'urn:oasis:names:tc:SAML:2.0:assertion', - '@Format': req.user.nameIDFormat, - '#text': req.user.nameID - }, - 'saml2p:SessionIndex' : { - '#text': req.user.sessionIndex - } - } - }; + '#text': req.user.sessionIndex + }; + } return xmlbuilder.create(request).end(); -} +}; SAML.prototype.generateLogoutResponse = function (req, logoutRequest) { var id = "_" + this.generateUniqueID(); @@ -324,10 +301,8 @@ SAML.prototype.getAuthorizeUrl = function (req, callback) { }; SAML.prototype.getLogoutUrl = function(req, callback) { - //var request = this.generateLogoutRequest(req); - var request = this.generateSaml2pLogoutRequest(req); + var request = this.generateLogoutRequest(req); var operation = 'logout'; - console.log(request); this.requestToUrl(request, null, operation, this.getAdditionalParams(req, operation), callback); }; From b9472d8e9d5713869ad3cd62c1a6cee9683aa327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vesa=20Poikaj=C3=A4rvi?= Date: Tue, 26 May 2015 12:03:23 +0300 Subject: [PATCH 3/3] Add test for SessionIndex --- test/tests.js | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/tests.js b/test/tests.js index fb144ed2..f3690b28 100644 --- a/test/tests.js +++ b/test/tests.js @@ -476,6 +476,40 @@ describe( 'passport-saml /', function() { }); }); + it( 'generateLogoutRequest', function( done ) { + var expectedRequest = { + 'samlp:LogoutRequest': + { '$': + { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', + 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion', + //ID: '_85ba0a112df1ffb57805', + Version: '2.0', + //IssueInstant: '2014-05-29T03:32:23Z', + Destination: 'foo' }, + 'saml:Issuer': + [ { _: 'onelogin_saml', + '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ], + 'saml:NameID': [ { _: 'bar', '$': { Format: 'foo' } } ], + 'saml2p:SessionIndex': + [ { _: 'session-id', + '$': { 'xmlns:saml2p': 'urn:oasis:names:tc:SAML:2.0:protocol' } } ] } }; + + var samlObj = new SAML( { entryPoint: "foo" } ); + var logoutRequest = samlObj.generateLogoutRequest({ + user: { + nameIDFormat: 'foo', + nameID: 'bar', + sessionIndex: 'session-id' + } + }); + parseString( logoutRequest, function( err, doc ) { + delete doc['samlp:LogoutRequest']['$']["ID"]; + delete doc['samlp:LogoutRequest']['$']["IssueInstant"]; + doc.should.eql( expectedRequest ); + done(); + }); + }); + it( 'generateServiceProviderMetadata', function( done ) { var samlConfig = { issuer: 'http://example.serviceprovider.com',