-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for per-participant bindings during SLO (#135)
- Loading branch information
1 parent
1d72b80
commit 46305eb
Showing
5 changed files
with
218 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"name": "samlp", | ||
"version": "7.0.1", | ||
"version": "7.1.0", | ||
"engines": { | ||
"node": ">=12" | ||
}, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ var fs = require('fs'); | |
var path = require('path'); | ||
var SPs = require('../lib/sessionParticipants'); | ||
const timekeeper = require('timekeeper'); | ||
const BINDINGS = require('../lib/constants').BINDINGS; | ||
|
||
var sp1_credentials = { | ||
cert: fs.readFileSync(path.join(__dirname, 'fixture', 'sp1.pem')), | ||
|
@@ -91,6 +92,91 @@ describe('samlp logout with Session Participants - Session Provider', function ( | |
}); | ||
}); | ||
|
||
function prepareOneParticipant(binding) { | ||
sessions.splice(0); | ||
sessions.push({ ...sessionParticipant1, binding: binding }); | ||
} | ||
|
||
function prepareTwoParticipants(secondBinding) { | ||
sessions.splice(0); | ||
sessions.push(sessionParticipant1); | ||
sessions.push({ ...sessionParticipant2, binding: secondBinding }); | ||
} | ||
|
||
function logoutGetSPInitiated(callback) { | ||
// SAMLRequest: base64 encoded + deflated + URLEncoded | ||
// Signature: URLEncoded | ||
// SigAlg: URLEncoded | ||
|
||
// <samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="samlr-220c705e-c15e-11e6-98a4-ecf4bbce4318" IssueInstant="2016-12-13T18:01:12Z" Version="2.0"> | ||
// <saml:Issuer>https://foobarsupport.zendesk.com</saml:Issuer> | ||
// <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">[email protected]</saml:NameID> | ||
// <saml:SessionIndex>1</saml:SessionIndex> | ||
// </samlp:LogoutRequest> | ||
request.get( | ||
{ | ||
followRedirect: false, | ||
uri: 'http://localhost:5050/logout?SAMLRequest=fVFNS8NAEL0L%2Foew900zaa1xaIOFIgSqBysevG03Uw1md%2BPOBoq%2F3m1aoVZ0DnOY97WPnbEybYcr9%2Br68EgfPXFIdqa1jAMyF7236BQ3jFYZYgwa14v7FeZphp13wWnXihPJ%2FwrFTD40zoqkWs7FXuBlnmf6OrsiqSEuAJrKm0JNJOntZLPRNBlDEfnMPVWWg7JhLvIMphJyCeMnKDADhPxFJM%2FkOZpHOM1EeXmRHGe2D8LBwZdvIXSMo9HWuY3y3Hed8yH9JFsTv6famdnolH7u8hBLVcvkznmjwt9tIYXh0tRyO1CRjGraRV17YhZlTL%2BlnTJdSyeZB%2FNfmesoib2q%2BMRdCUfuj%2BO34oCd%2FWj5BQ%3D%3D&Signature=NkobB0DS0M4kfV89R%2Bma0wp0djNr4GW2ziVemwSvVYy2iF432qjs%2FC4Y1cZDXwuF5OxMgu4DuelS5mW3Z%2B46XXkoMVBizbd%2BIuJUFQcvLtiXHkoaEk8HVU0v5bA9TDoc9Ve7A0nUgKPciH7KTcFSr45vepyg0dMMQtarsUZeYSRPM0QlwxXKCWRQJDwGHLie5dMCZTRNUEcm9PtWZij714j11HI15u6Fp5GDnhp7mzKuAUdSIKHzNKAS2J4S8xZz9n9UTCl3uBbgfxZ3av6%2FMQf7HThxTl%2FIOmU%2FYCAN6DWWE%2BQ3Z11bgU06P39ZuLW2fRBOfIOO6iTEaAdORrdBOw%3D%3D&RelayState=123&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1', | ||
}, | ||
function (err, response) { | ||
if (err) return callback(err); | ||
callback(null, response); | ||
} | ||
); | ||
} | ||
|
||
function logoutPostSPInitiated(callback) { | ||
// SAMLRequest: base64 encoded + deflated + URLEncoded | ||
// Signature: URLEncoded | ||
// SigAlg: URLEncoded | ||
|
||
// <samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="samlr-220c705e-c15e-11e6-98a4-ecf4bbce4318" IssueInstant="2016-12-13T18:01:12Z" Version="2.0"> | ||
// <saml:Issuer>https://foobarsupport.zendesk.com</saml:Issuer> | ||
// <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">[email protected]</saml:NameID> | ||
// <saml:SessionIndex>1</saml:SessionIndex> | ||
// </samlp:LogoutRequest> | ||
request.post({ | ||
followRedirect: false, | ||
uri: "http://localhost:5050/logout", | ||
json: true, | ||
body: { | ||
SAMLRequest: "PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c2FtbHA6TG9nb3V0UmVxdWVzdCB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0icGZ4NmZlNjU3ZTMtMWE3Zi04OTNlLWY2OTAtZjdmYzUxNjJlYTExIiBJc3N1ZUluc3RhbnQ9IjIwMTYtMTItMTNUMTg6MDE6MTJaIiBWZXJzaW9uPSIyLjAiPg0KICAgICAgICA8c2FtbDpJc3N1ZXI+aHR0cHM6Ly9mb29iYXJzdXBwb3J0LnplbmRlc2suY29tPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4NmZlNjU3ZTMtMWE3Zi04OTNlLWY2OTAtZjdmYzUxNjJlYTExIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT55SnpIbmRqL3NuaVJzTG1kcHFSZ0Yvdmp6L0k9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPk56bU42R0RLcHNpMVU4NndaTXNjWjY2aExHNDVhMzhhMGhvaCtpdFdCTWQzNS9RMnF1Y2N2NEJaTGhSbU1xYmFIL3l4VnZ4bWUvWXExR24xbEkrVlpwZkZsYURXQnZTcXUxdWJVemVEbEtVUDdHUmVnakNSTFErSkhxZnQ2aHRDdENQdkttQ0NTaVNEVlZydmcvc0ZLVXBuVDhPWEhkK25ENDBLSVQ4NHQ2OERiM2pTN3g2amx6VDMzYk1Vdm83dVNFUDVnSnFUbG9RMVVWY280WmszUGVxK0tDOWF6TUFkVHVnMWZZRDJXVWtXOEZCd084b1ZBUWpDMGo4VkVyVVpiUUpRS2hhdTMxcjNVcU1VUExNS0NJaFZxZ0tPRVd6MWt1a1NWY2MzdTJjR0owT1FJU093N0xQbkRDSTdPclVMaGU4NEJESTMzR01JMDNXazFMNG5Mdz09PC9kczpTaWduYXR1cmVWYWx1ZT4NCjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YS8+PC9kczpLZXlJbmZvPjwvZHM6U2lnbmF0dXJlPg0KICAgICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDplbWFpbEFkZHJlc3MiPmZvb0BleGFtcGxlLmNvbTwvc2FtbDpOYW1lSUQ+DQogICAgICAgIDxzYW1sOlNlc3Npb25JbmRleD4xPC9zYW1sOlNlc3Npb25JbmRleD4NCiAgICAgIDwvc2FtbHA6TG9nb3V0UmVxdWVzdD4=", | ||
RelayState: "123", | ||
}, | ||
}, | ||
function (err, response) { | ||
if (err) return callback(err); | ||
callback(null, response); | ||
} | ||
); | ||
} | ||
|
||
function logoutGetIDPInitiated(callback) { | ||
request.get({ | ||
followRedirect: false, | ||
uri: 'http://localhost:5050/logout' | ||
}, function (err, response) { | ||
if(err) return callback(err); | ||
|
||
callback(null, response); | ||
}); | ||
} | ||
|
||
function assertPostResponse(response) { | ||
// Ensure we get a POST response, | ||
// this means responding with an HTML form that will self-submit. | ||
// The rest is covered by other tests. | ||
expect(response).to.be.ok; | ||
expect(response.statusCode).to.equal(200); | ||
} | ||
|
||
function assertRedirectResponse(response) { | ||
// Ensure we get a Redirect response, | ||
// The rest is covered by other tests. | ||
expect(response).to.be.ok; | ||
expect(response.statusCode).to.equal(302); | ||
} | ||
|
||
describe('HTTP Redirect', function () { | ||
describe('SP initiated - Should fail if No Issuer is present', function () { | ||
var logoutResultValue; | ||
|
@@ -800,6 +886,66 @@ describe('samlp logout with Session Participants - Session Provider', function ( | |
}); | ||
}); | ||
}); | ||
|
||
describe('SP initiated - 1 Session Participant with POST binding', function () { | ||
var logoutResponse; | ||
|
||
before(function () { | ||
prepareOneParticipant(BINDINGS.HTTP_POST); | ||
}); | ||
|
||
before(function (done) { | ||
logoutGetSPInitiated(function(err, response){ | ||
if (err) return done(err); | ||
logoutResponse = response; | ||
done(); | ||
}); | ||
}); | ||
|
||
it('Should return POST request', function () { | ||
assertPostResponse(logoutResponse); | ||
}); | ||
}); | ||
|
||
describe('SP initiated - 2 Session Participants with POST binding', function() { | ||
var logoutResponse; | ||
|
||
before(function () { | ||
prepareTwoParticipants(BINDINGS.HTTP_POST); | ||
}); | ||
|
||
before(function (done) { | ||
logoutGetSPInitiated(function(err, response){ | ||
if (err) return done(err); | ||
logoutResponse = response; | ||
done(); | ||
}); | ||
}); | ||
|
||
it('Should return POST request', function () { | ||
assertPostResponse(logoutResponse); | ||
}); | ||
}); | ||
|
||
describe('IDP initiated - 1 Session Participant with POST binding', function() { | ||
var logoutResponse; | ||
|
||
before(function () { | ||
prepareOneParticipant(BINDINGS.HTTP_POST); | ||
}); | ||
|
||
before(function (done) { | ||
logoutGetIDPInitiated(function(err, response){ | ||
if (err) return done(err); | ||
logoutResponse = response; | ||
done(); | ||
}); | ||
}); | ||
|
||
it('Should return POST request', function () { | ||
assertPostResponse(logoutResponse); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('HTTP POST', function () { | ||
|
@@ -1374,6 +1520,46 @@ describe('samlp logout with Session Participants - Session Provider', function ( | |
expect(response.body).to.equal('Invalid Session Participant'); | ||
}); | ||
}); | ||
|
||
describe('SP initiated - 1 Session Participant with Redirect binding', function () { | ||
var logoutResponse; | ||
|
||
before(function () { | ||
prepareOneParticipant(BINDINGS.HTTP_REDIRECT); | ||
}); | ||
|
||
before(function (done) { | ||
logoutPostSPInitiated(function(err, response){ | ||
if (err) return done(err); | ||
logoutResponse = response; | ||
done(); | ||
}); | ||
}); | ||
|
||
it('Should return Redirect request', function () { | ||
assertRedirectResponse(logoutResponse); | ||
}); | ||
}); | ||
|
||
describe('SP initiated - 2 Session Participants with Redirect binding', function() { | ||
var logoutResponse; | ||
|
||
before(function () { | ||
prepareTwoParticipants(BINDINGS.HTTP_REDIRECT); | ||
}); | ||
|
||
before(function (done) { | ||
logoutPostSPInitiated(function(err, response){ | ||
if (err) return done(err); | ||
logoutResponse = response; | ||
done(); | ||
}); | ||
}); | ||
|
||
it('Should return Redirect request', function () { | ||
assertRedirectResponse(logoutResponse); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
|
@@ -1429,6 +1615,7 @@ describe('samlp logout with Session Participants - Session Provider', function ( | |
} | ||
}, function (err, response){ | ||
if (err) { return done(err); } | ||
|
||
expect(response.statusCode).to.equal(200); | ||
$ = cheerio.load(response.body); | ||
var SAMLResponse = $('input[name="SAMLResponse"]').attr('value'); | ||
|