diff --git a/README.md b/README.md index 491ad68e3..33983dce8 100644 --- a/README.md +++ b/README.md @@ -48,10 +48,10 @@ Config parameter details: * `host`: host for callback; will be combined with path and protocol to construct callback url if `callbackUrl` is not specified (default: `localhost`) * `entryPoint`: identity provider entrypoint * `issuer`: issuer string to supply to identity provider - * `cert`: see 'security and signatures' - * `privateCert`: see 'security and signatures' + * `cert`: see [Security and signatures](#security-and-signatures) + * `privateCert`: see [Security and signatures](#security-and-signatures) * `decryptionPvk`: optional private key that will be used to attempt to decrypt any encrypted assertions that are received - * `signatureAlgorithm`: optionally set the signature algorithm for signing requests, valid values are 'sha1' (default) or 'sha256' + * `signatureAlgorithm`: optionally set the signature algorithm for signing requests, valid values are 'sha1' (default), 'sha256', or 'sha512' * Additional SAML behaviors * `additionalParams`: dictionary of additional query params to add to all requests * `additionalAuthorizeParams`: dictionary of additional query params to add to 'authorize' requests @@ -104,7 +104,7 @@ app.get('/login', As a convenience, the strategy object exposes a `generateServiceProviderMetadata` method which will generate a service provider metadata document suitable for supplying to an identity provider. This method will only work on strategies which are configured with a `callbackUrl` (since the relative path for the callback is not sufficient information to generate a complete metadata document). -The `decryptionCert` argument should be a certificate matching the `decryptionPvk` and is required if the strategy is configured with a `decryptionPvk`. +The `decryptionCert` argument should be a public certificate matching the `decryptionPvk` and is required if the strategy is configured with a `decryptionPvk`. ## Security and signatures @@ -117,7 +117,7 @@ Authentication requests sent by Passport-SAML can be signed using RSA-SHA1. To s privateCert: fs.readFileSync('./cert.pem', 'utf-8') ``` -It is a good idea to validate the incoming SAML Responses. For this, you can provide the Identity Provider's certificate using the `cert` confguration key: +It is a good idea to validate the incoming SAML Responses. For this, you can provide the Identity Provider's public signing certificate using the `cert` configuration key: ```javascript cert: 'MIICizCCAfQCCQCY8tKaMc0BMjANBgkqh ... W==' diff --git a/lib/passport-saml/saml.js b/lib/passport-saml/saml.js index 2ef65955f..42d4c208b 100644 --- a/lib/passport-saml/saml.js +++ b/lib/passport-saml/saml.js @@ -60,13 +60,13 @@ SAML.prototype.initialize = function (options) { options.cacheProvider = new InMemoryCacheProvider( {keyExpirationPeriodMs: options.requestIdExpirationPeriodMs }); } - + if (!options.logoutUrl) { // Default to Entry Point options.logoutUrl = options.entryPoint || ''; } - // sha1 or sha256 + // sha1, sha256, or sha512 if (!options.signatureAlgorithm) { options.signatureAlgorithm = 'sha1'; } @@ -114,6 +114,10 @@ SAML.prototype.signRequest = function (samlMessage) { samlMessage.SigAlg = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; signer = crypto.createSign('RSA-SHA256'); break; + case 'sha512': + samlMessage.SigAlg = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'; + signer = crypto.createSign('RSA-SHA512'); + break; default: samlMessage.SigAlg = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'; signer = crypto.createSign('RSA-SHA1'); @@ -157,7 +161,7 @@ SAML.prototype.generateAuthorizeRequest = function (req, isPassive, callback) { '@IssueInstant': instant, '@ProtocolBinding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', '@AssertionConsumerServiceURL': self.getCallbackUrl(req), - '@Destination': self.options.entryPoint, + '@Destination': self.options.entryPoint, 'saml:Issuer' : { '@xmlns:saml' : 'urn:oasis:names:tc:SAML:2.0:assertion', '#text': self.options.issuer @@ -371,7 +375,7 @@ SAML.prototype.getAuthorizeForm = function (req, callback) { .replace(/"/g, '"') .replace(/</g, '<') .replace(/>/g, '>') - // Add other replacements here for HTML only + // Add other replacements here for HTML only // Or for XML, only if the named entities are defined in its DTD. .replace(/\r\n/g, preserveCR) // Must be before the next replacement. .replace(/[\r\n]/g, preserveCR); @@ -552,21 +556,18 @@ SAML.prototype.validatePostResponse = function (container, callback) { if (!self.options.decryptionPvk) throw new Error('No decryption key for encrypted SAML response'); - var encryptedDatas = xpath( encryptedAssertions[0], "./*[local-name()='EncryptedData']"); - if (encryptedDatas.length != 1) - throw new Error('Invalid signature'); - var encryptedDataXml = encryptedDatas[0].toString(); + var encryptedAssertionXml = encryptedAssertions[0].toString(); var xmlencOptions = { key: self.options.decryptionPvk }; - return Q.ninvoke(xmlenc, 'decrypt', encryptedDataXml, xmlencOptions) + return Q.ninvoke(xmlenc, 'decrypt', encryptedAssertionXml, xmlencOptions) .then(function(decryptedXml) { var decryptedDoc = new xmldom.DOMParser().parseFromString(decryptedXml); var decryptedAssertions = xpath(decryptedDoc, "/*[local-name()='Assertion']"); if (decryptedAssertions.length != 1) throw new Error('Invalid EncryptedAssertion content'); - if (self.options.cert && - !validSignature && + if (self.options.cert && + !validSignature && !self.validateSignature(decryptedXml, decryptedAssertions[0], self.options.cert)) throw new Error('Invalid signature'); @@ -574,7 +575,7 @@ SAML.prototype.validatePostResponse = function (container, callback) { }); } - // If there's no assertion, fall back on xml2js response parsing for the status & + // If there's no assertion, fall back on xml2js response parsing for the status & // LogoutResponse code. var parserConfig = { @@ -708,7 +709,7 @@ SAML.prototype.processValidlySignedAssertion = function(xml, inResponseTo, callb } } } - + // Test to see that if we have a SubjectConfirmation InResponseTo that it matches // the 'InResponseTo' attribute set in the Response if (self.options.validateInResponseTo) { @@ -916,13 +917,13 @@ SAML.prototype.generateServiceProviderMetadata = function( decryptionCert ) { } } }, - '#list' : [ + 'EncryptionMethod' : [ // this should be the set that the xmlenc library supports - { 'EncryptionMethod': { '@Algorithm': 'http://www.w3.org/2001/04/xmlenc#aes256-cbc' } }, - { 'EncryptionMethod': { '@Algorithm': 'http://www.w3.org/2001/04/xmlenc#aes128-cbc' } }, - { 'EncryptionMethod': { '@Algorithm': 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc' } }, + { '@Algorithm': 'http://www.w3.org/2001/04/xmlenc#aes256-cbc' }, + { '@Algorithm': 'http://www.w3.org/2001/04/xmlenc#aes128-cbc' }, + { '@Algorithm': 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc' } ] - }; + } } if (this.options.logoutCallbackUrl) { diff --git a/package.json b/package.json index ea1cfea02..fd42c1d52 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "passport-saml", - "version": "0.14.0", + "version": "0.16.1", "licenses": [ { "type": "MIT", @@ -31,23 +31,22 @@ "main": "./lib/passport-saml", "dependencies": { "passport-strategy": "*", - "q": "1.1.x", + "q": "^1.5.0", + "xml-crypto": "^0.9.0", + "xml-encryption": "~0.10", "xml2js": "0.4.x", - "xml-crypto": "0.8.x", - "xmldom": "0.1.x", - "xmlbuilder": "2.5.x", - "xml-encryption": "~0.7" + "xmlbuilder": "^8.2.2", + "xmldom": "0.1.x" }, "devDependencies": { - "body-parser": "1.9.x", - "ejs": "1.0.x", + "body-parser": "^1.17.1", "express": "4.x", "jshint": "*", "mocha": "*", + "passport": "0.3.x", "request": "*", "should": "*", - "sinon": "^1.10.2", - "passport": "0.3.x" + "sinon": "^2.1.0" }, "engines": { "node": ">= 0.8.0" diff --git a/test/samlTests.js b/test/samlTests.js index 9a6ae158c..98e01b136 100644 --- a/test/samlTests.js +++ b/test/samlTests.js @@ -45,7 +45,7 @@ describe('SAML.js', function() { // NOTE: This test only tests existence of the assertion, not the correctness it('calls callback with saml request object', function(done) { saml.getAuthorizeUrl(req, function(err, target) { - url.parse(target, true).query.should.have.property('SAMLRequest'); + should(url.parse(target, true).query).have.property('SAMLRequest'); done(); }); }); diff --git a/test/tests.js b/test/tests.js index 4e5202951..9ee27aa94 100644 --- a/test/tests.js +++ b/test/tests.js @@ -29,6 +29,20 @@ describe( 'passport-saml /', function() { expectedNameIDStartsWith: 'ben', mockDate: '2014-05-27T23:29:35.426Z' }, + { name: 'Okta -- valid encrypted response should succeed', + samlResponse: { + SAMLResponse: 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDJwOlJlc3BvbnNlIHhtbG5zOnNhbWwycD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly82NGY0MDk0Zi5uZ3Jvay5pby9zc28vc2FtbC9jYWxsYmFjayIgSUQ9ImlkMTk1MjM4OTMzOTcwNDQ4MjIzOTQwNDk3IiBJblJlc3BvbnNlVG89Il9jNjA1MzdkYWQzNGZhNGVjYjYxMyIgSXNzdWVJbnN0YW50PSIyMDE2LTA4LTE5VDAxOjEzOjM4LjEzOVoiIFZlcnNpb249IjIuMCI+PHNhbWwyOklzc3VlciB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6bmFtZWlkLWZvcm1hdDplbnRpdHkiPmh0dHA6Ly93d3cub2t0YS5jb20vZXhrN3hkaTZheFBmb21iengwaDc8L3NhbWwyOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz48ZHM6UmVmZXJlbmNlIFVSST0iI2lkMTk1MjM4OTMzOTcwNDQ4MjIzOTQwNDk3Ij48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNzaGEyNTYiLz48ZHM6RGlnZXN0VmFsdWU+enQ3eG5yTDB1Vmt6azN1NHhkS3hVR0ZtbHVLamM4eXlDOWZvanJ4NXFDbz08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6U2lnbmF0dXJlVmFsdWU+ZUZlczNUUEIvZVFlUVBtUHBPYlA0UDNRWklKRGMxY1cwMk5UOHJlVEp1MG9lZElDTm8vTkJEeE9rMWJoODFJMzlMdi90MWRFM0Z3azBrZ0kzRUswV0s0UVpsSWZ2WkIrTkpPSlRjZW9CUnptTXRBeHI5cVlORWlHSWxZeGdwS1BDaG95OHQzcllMV3ZCZVpJc2pKOC9iYmRudXhjSFY3bXpveFkyNHdtYXFucXExNG5QSTFBZ0lIY1NnTVRhL1lqaFJwWjJlU0o2TU9FMU0vNDByL3VvRUlPWDVjMFVoSE1Gbzh3Yml2NCtvaTJPK2RPOVdha3BDN1Y5cHVGelU0OVF6MGR6bDFXaFIwYlp4VG1TYXI2WUY2NXMwZk5DUnorSGJ5a1h3eFZ4OFo0TTUxRUJHN1NMdWlQVFVJTjFNWVRXZXVoZll6MS9Pc2YvcGoxbHFLYlZBPT08L2RzOlNpZ25hdHVyZVZhbHVlPjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSURvRENDQW9pZ0F3SUJBZ0lHQVZhWjA0UE9NQTBHQ1NxR1NJYjNEUUVCQlFVQU1JR1FNUXN3Q1FZRFZRUUdFd0pWVXpFVE1CRUcKQTFVRUNBd0tRMkZzYVdadmNtNXBZVEVXTUJRR0ExVUVCd3dOVTJGdUlFWnlZVzVqYVhOamJ6RU5NQXNHQTFVRUNnd0VUMnQwWVRFVQpNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RVRBUEJnTlZCQU1NQ0daeWIyNTBZWEJ3TVJ3d0dnWUpLb1pJaHZjTkFRa0JGZzFwCmJtWnZRRzlyZEdFdVkyOXRNQjRYRFRFMk1EZ3hOekU0TkRVek1Wb1hEVEkyTURneE56RTRORFl6TVZvd2daQXhDekFKQmdOVkJBWVQKQWxWVE1STXdFUVlEVlFRSURBcERZV3hwWm05eWJtbGhNUll3RkFZRFZRUUhEQTFUWVc0Z1JuSmhibU5wYzJOdk1RMHdDd1lEVlFRSwpEQVJQYTNSaE1SUXdFZ1lEVlFRTERBdFRVMDlRY205MmFXUmxjakVSTUE4R0ExVUVBd3dJWm5KdmJuUmhjSEF4SERBYUJna3Foa2lHCjl3MEJDUUVXRFdsdVptOUFiMnQwWVM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDdnBsUU8KTlZ3a25SeTFpQm5hb1p0c096MjhBN1hXMnRScEZXKzBMYTdSSmV4YnppSXdFeTFiUFpFTmhmd2pQWkExb0hIWnFpNWwzMTVCeFhLVwpKcW1tTm1iRENGRG8rL0ZZRkNvSFhsaWlMbTl2cURiUjFicjZCeXFlWTBHZnh5VFBLSFp4YjJGU2VzMzBUZmZEa25wTVFkLzhrQTlZCldhVzV4RGx1Mml2V0pJK3NmY09KT01kNnQrZ2NmWGo1OGE1ZlA4TXdtNlkyMjBLZVpTdnJWcEVWMktEcDlobG43Zmhob3hIWjdLL0IKWWJpZHFkd0x6ZVVRWHBiNkxJcnh0S2R1ZzJGb2ZTK09OczZ5TElRUm1yYkNCN1NWWDFRQThKSW5NbitmenJHdFptRmlIUjBhRmJ5aAppTzc4di91ZkRhNlMrWHBZeXAyYjZENFNuemVnZ25vYkFnTUJBQUV3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUoyd2NGVmZmRkhTCmQ5cGo2UmdvTkhYWkJzV3AwSFVack5la2lTYmdvbXI0dFNEZWZXdEtiMDRuRklsUnl0ZlZzL2s3NHdtYk5pUkNFOG5EVkJyQkRGQS8KK1R2LzNQb3daWEhqWEtCb2ZVdVNjVFA0L1R3MU4veXdmN1YrWFk1a1YzVm1MQkw2YXgrVUxKYXVSL1lHSUlNc0ljL3JTMkQwNGFBYwpTY1U5cHFWaDJNTDduVEg3Z0ZxWXJ4eXBhdm1WazZLOTR2TGpzMGdnRjJUR3A3dFhDUmplT2xQUEpTK01PSkhKaFRCV1lGV3ZCTGNsClUzemNyaTN3czdHcUpNcGVpSGE3ck1vSFYwb254V3NaVFpXNTd5YmFJV0tMdDFnb0Fvb0M3aHEwcng3b05sT3ZyeXM1bGxsaEJ5U1kKWUMzeWNxY2EvRDArR3hYTGNFcjlRd1A3VFZ3PTwvZHM6WDUwOUNlcnRpZmljYXRlPjwvZHM6WDUwOURhdGE+PC9kczpLZXlJbmZvPjwvZHM6U2lnbmF0dXJlPjxzYW1sMnA6U3RhdHVzIHhtbG5zOnNhbWwycD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48c2FtbDJwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPjwvc2FtbDJwOlN0YXR1cz48c2FtbDI6RW5jcnlwdGVkQXNzZXJ0aW9uIHhtbG5zOnNhbWwyPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj48eGVuYzpFbmNyeXB0ZWREYXRhIHhtbG5zOnhlbmM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jIyIgSWQ9Il85ZThmZDJjZTRhZDAyMTJjOThlNzA5MWNhODc2NWZiNCIgVHlwZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjRWxlbWVudCI+PHhlbmM6RW5jcnlwdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI2FlczI1Ni1jYmMiIHhtbG5zOnhlbmM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jIyIvPjxkczpLZXlJbmZvIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6UmV0cmlldmFsTWV0aG9kIFR5cGU9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI0VuY3J5cHRlZEtleSIgVVJJPSIjXzJhZWE3YTY1MWRiYjY4NzkwMmM0ODM0MzJlZDg1NzgwIi8+PC9kczpLZXlJbmZvPjx4ZW5jOkNpcGhlckRhdGEgeG1sbnM6eGVuYz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjIj48eGVuYzpDaXBoZXJWYWx1ZT5KQVJJWlJOMnFPRFhKZ2F2TW9xZXFmZng4QTZLaGcwa0xBT3JYSzQzdW1KVWhpTUI2MzM4dE9IbHNYYWlhdjRnSDZHUG9GbzM0Y1VrWEVkY2VEb2dpSXBKSGNwWnJ3YUVaZW9wM1Q3aHpoSGxRUnBISk9aVXQrWWRqVnliQy9JMmVuNmdGMjdwdVpkTFhIU2dvQkd0akprb1Q1dGp2Yko1WWs5WVdYaHp5eXNva3djNHczNmpjdlVRVEtBUE1nQXoraUJ5Tlc0ajBLcXdHU2RCMXpqeEZjOXhvYy9Ua0FxZlcwSjFxWGJlWG5scmh6SFdQNC9kck9YK0tLS1pxM3VtYnBOZkQ2RXo1cVRueWt4ajhwbnIyV2RFZVVDWldkOTZZY3MycWVXbXY5RUlncVdydzVud3JLaE5qNVJmSzA2NXdUZWc2MFdLWjU5MHdXRjlMek0xZ1dFL2l0U0hDZ2N2NmFPSjNhRVRHV1AvU2pESlFVQmFZY2ZMeFlFNU50clF2ak5HcHVIRlkvNVhHdEIzS1dqWElkWlVFMW91ZHRqNjY0T1podVEyUERTQ2ZmSC92aGJKZ1c2Z0szaXYxM3RZeUJTaUJ6bVVzdWVhSE9HdUZJeUtpaDdxUzh3dFRHTGRjWDZuWTJaRkJZSmZQZXZaMTUzb2JKdXVvM3FFNnVndkRRTUgwL0VwZlhZZTRpUFVtbHQ5OXcwWWdTNEt0dTZaMWFZVnpYZGdWY29maVlVQzhzdzJiczBSQUNiQzVMa1Y3a1ROMndYVStuTjBvQ1lLaUxML1oxWmswbGx0c1gvV1BjY09PR3pjWENMUkwyRmxvdjhyM3BOeVNMV1AweGFCUUdodUlZNmMvYVJvRDZZOXphdG9seWFzeTVHbEJSQVJOK3Ixdy9tWW9laEJ5WnVxdnVINmhDWGF5bnU1L2szR3Q4emdoc1FoNjVwVVYvbDRQa0prMThmNGRzbEdyMUh4eWRJVjQ2YldtVzFwTlNsQ01PeXhBcW5IUEhWd1BBTjJHN3ZpRGZQbkpZZEhXOXlZdkZTUTBhczM5OGtyNkNRWnlJMXRWWXJDZHNGdllLRURrcTI2MTNHWmxsMjRPaUpiYnVHV0VJUk52RDR3VzdsSmlmYk1pQnZkSDNNci9PUHNHYStmamNmaWM3MlpGSnU5TUxoZTBSSnQ2aTVsdGxPdXB5ZU4xVjE1QUR0TnRFZ01IdzRFS3ZkUktWUDVnZytmL3FLQVZLdkV0dlVJOTRSV21DYzZEQ29BVmNRSnJzYnkxblhMOEdxcFZ0V0Qyd0VSd1pWWUh6dVlyM0UrTUFJNXl6eEJOcFlwL3kwTEVjeEdIYkZiUFRacXhuWk9WL1FaL1laWDNKK2svZXdseVhpY2RpWFNXN25RMnB2N0Rna2RqYlQ5NmRXa1hwbDlHQ0JmZTVoVGJXTDZscksxcW9oODYzSHA5c2dOcS92RjArYUlMWFZQK3Z5OHRxZ0F0MDZSRFlKaFRZWWVOSHY1c3luTXRiV2hPREh3TEIrdUVHVWtNZW5mUm9zWDl5N21XSkxIWmdMNGNwektwT1A5WlBhbktYT1RvZVcyanM5TmEwdURDUGI0YkdHdkdGTHh6Mm05U05ETmtDTFZFaEI3aC81d0dabHdYbXpVanZhQlprYnhrbGFEb1dYVG5iQU9jT01Sa1RQRks1d0JYYVRaTkFsUkhpOWh5TWQ2WkJ3OVp2RklFczY4K2wxcEhRY0dKT0RYR1JtYUZNUVMrQlVRV1JxcnNoVXpTY0d1cVljdTVsc1FtRExTSFdnaitHRnEycGE0eGQwZGJRSVN0MDdETGo1RUtmRFUzOXNCRGo1bncvd2FUNzhuYmtXMDd6cE9PbFFEd0F5dG5aRWthdEJtMzUyQnBhaEg2SkxRQzFTNG5TWTlKbmhsS09EOHJLRE5NVTR6VFJOU3FxT0JTRmlwMlRJaU0ydXYvSlVPSkNpRUNYSkFaY05vcEhwZ2UvNE5icU5ycDlzYlBTM1c1T0ZpMjdWMktON0htVk9YY1JWY2FNenZsS1YrRDNIdVUxeGxPdnlGTWI4WFhtZGRyRFV1dDBHWEhTVmNpYys1TDBuUWc4UXVKMHBIVzM1MkVPMHJ2NnRTV3cwUUV6NzZJUzNhWnkwZmkxVC82ajQwTVptR1E1NFJPTDBrRlZwU285UWhTWjgrMnE4RnFGOW5DYWJkOVFzcUVSRFQ3VzhqaWo3QklMVjZ3azMra1lkMjZReGhObmlOOHJkYTZvRnpXb25Ddzl2dzUwUHRwWS8vTUpvd3FLWGFhRFNzY2R4K3FDRWVBWm0vNWxYZFdMb2tHaXRhRU56SEtXR05vYlpJTnVyM29lS25lYmVuMVY0amlvb3RiQjA5WkhHR1R6ZGNDSHZhUXZMWjUzSndTTFdYYXM4NXF0L0ZUVHpvM3NPYUlESFBJMWVQNUhrdENQMHFTL0pyeGZFbVhtdkRrQUt4L2x6cGhLY0tpU1cvWmdqMVh1OTViZURqTklIcVBVZzF5M0d3bTBWbzlJcjR5cGhtY1RoMXZtRTV1bHNlVXJ4SlJ6TEVscGZzR2MxeU5QNHhHY1NsL05HODd6SHdMTTFIRlN5MWdCN0FJTFY4VkpCb29XdHJXQ3pqL1Y5YVBBeU9ySTFYaUpOQmlNamk0SnpCc0VvR1pNQXREc0lyNk5kNlZ2ejlvYUlubUZuUXRjWHE2c0wyTE11NjcvUFlzSGhtN3E3UUFrbHQ5WXNOaGpKUWlzcENkbFdHRk9yc0lFdWpTbGJGS0gvUldyRUwzWWJOdUV0bTRqUWY3MnNQUEMyT0M3c0JqMDZoQjVVZlZUcDM5SlJtc3pmNGUzVE52NHo0SEUramIxVlNGQkQrM0tnaHpwQTNjREVnZEphQmE2ajFrbnJ6RjJUOUZudDJrTTBFSmwydUxuS0dCUnBSU2IrZ2FUWVh3NjlaaUtJa2kyY3Q3dS9sd1BpUXFRU2FjSzJ2M3FLNmtWNFUyb09Xd3BNTkI1WXpPeE1JZTBGeEJoZFl0dEJPT0FNM0dGOWlIaFJObWlhMG5GelVRcXc0b2RzTWVRaU84cnhWNDZzRGZ6bmRpVjc3SzNaaWR5anpCalRPMEpBK0R1NU9lZ1dTaUdTZTNzdUx3Rll0U1VKbTZIN3J0am1hbEhKNEMrTisvdEJmNHVVdlRXaFFkejJOUHpiblV2bmZ4c1YyazlFMTRZSkg1UjZTUndTY1czQ1MzV2EyYmZwSnUvSUg4cGZ4RTVzQmRzZlBmMjNYR2FBdVBocmt0TVBRUzdQaEJWeGkzUk5vb3kwd0NGaTZRMWFTT2FxREJyNS9Gc1cxNy9uT2NOL0tDYmt2NFdiZlZ1eGZBSGQrSXl4M1RTbTRqVFlPY0QvZXcxLzRPT2QxQjdVK2g5Qm5kSjIwRWZiQXNxZVpuRlNyWnpFMWJLRjFwK05VaDRaMnBUMlVOYXo0WEQ5MXA1Z3JPZUsvTkdnUEJvSjIxVis4NXpISmpncjNsYWg4NVdMNFV3YUhHL2tuOTAzZGdqMTR5clYzTis2OXFJeW04ckxtWFFCeHRJYmJaaXFJM0RTNXRJaWJkd3ZUQzU3UnNzaUJ0ZFRFWWVnbFI1SGpTOWQ1ZkZpWjhNeGxsMGhaUXJaS3NERHZUZjMrZjBSVzNDV3RLTFZDRDRtaUw5WUkybXl0SXM3Q3JNSDZ0anFVbWNoNjZ2eTJJRFhqUXltVGc3cXMvSGRwQ2J2U0FvdWt2cUJlam9FRVVwSG5scko3K3B6SmJiUm5jQXFpUDVQd1VzWGZNNXpxbjJueGRxT2RUV3VYOTFGc1FUU2JrcUdHMkNEWHRiUjFiK3JiSVZFVWNHdHgvK2c1eVNYNnVFcFdYV2ZnZ1lGQzUvMWJuTUdmZ0VJYUZnVkp3L20wYVg5b3I3dzQ1T1VqNGpnNHdENG5sd3VuR1ZJUE15YUR5d2dxeWZCOWw2S3AwMjZPa2ZldnlVMVNiQkIybTN0bkZtTDhCSEVuSVplbEhyT2luV1dqMXBTc2M1WkxySU9nRWhIMm1TY3Eya3BSOXdjbU9obkRTV3A2d2h1N0RjTTZnRkw3ZGJ3aU1hSGlTMzNYR05TQlVpRWVQYnJUTVl0L0l6TjVjSGpIM0JFZ2JwY3lRMERnNHEzaVhSTElkYUM0eS9nWHkyRU1iZEFYMFRlUzRoVmxscEtFcEJpMmNsVFgwZWJFWk9aTDFpMWhpRHh6aTJGcG5xNk1qd2hrYmhzT0ZPMGtGYzdYWWVndGZFeGFsUEFWRHR1VUNRb3BScjBtM2s1b3dYSksvNUtUUktRaW5sUm1LakttN1RzNGdsRUhycHpWYWhkV1JZSWtuU2hrV3cxMnNHODdlTFJqa1pZbkxuaDZLMkEvNzlXTkpMZXYwQXlpa1VjbjlKaFBRTS9oUjBxWWc3WXQ4ZmxrQWtaOGk5Snp2Z0pWRHkzRzMySWdtY2J1MjVRTWZaUzZJV0hUSmJ1Uk5ndHNGdm1ndjhtQUZ6UnV3bUdvaXVWUmtTVURRS09VRCtObDdUcm12b0NPWDhiZFgvOHNMZnV0bGZ4YU5DcXRVN2gxcEQ5R1JQTHVSUzUvdzZVSkc5Q0JOM3JMZS9Ha20zQTFDMElaY2E3eEYwZnAzQ3JpQlN2NzFpN2VkM3crcGt2cHVMSUZ3NHZsV2thRkplZTZuQkl4WEpVMmZFMmVkTWs4RXFwSXg5SHlaZk9IbVRVY0QzN2tvbGJPTXlUeU9pQ1RNYjFreFFCNHR6bFh2VG5GK3l2Z3JPUm5GZVVYMmUrNk1lQWY4cXc2TUUwQ3NQOTBqbDR4dHpIQUtxZFlLWjNaSFhyUkZmeEJyWXY4bEN2c0ZGWEtOY25hU25WWkJ2bFVQekI2NmZYMG9WWTIxWkxwMHRUMUE2NzF5aU1odktOTHRFckZXQm9COTFTTVI1SWFlMnlidDE2cTVCWWJod214K3ZxYUo5Zjk1QzVRNUZ2ZWt4bGg3Z2gva1ZlMDl2WXI1cStpVFNqdEo1YWpvcXRBTklJejF5dDAwR1o3RVViRnBvN0VSVGk4c0E4V2JTUWFCZnJjTHljRWw0SVdjVGRTdjhYMjVIcytWeGgvM3FDQVlMdDRjam5Pa1ltS21xamc4c2hLN1RSQmdDcnFWZi84RjdqN0ZjaW9PSTBHakZYZ2tHQWExRXl3dk9RM1k5VXhNTFAvOTBIOUVaSElBRGVZckhpbzAxM0FUdlhNaTY2bU9ETUQrWXRCb21sR2YwRFYxU0g3Qi9wR1hxYS9uTFFxQUE1cDFrZEFBa0t1KzQzdStzNnVhOGk2bHRnMnNDdVlnQ0JzYUFhSXQxWXJQOGp3MG8wZEUvYmo4TTF0Y2JXOFo4UFIwb0VFOGNuK004dnVoU3JTZ2l4ZXl6bHVJSWEzR21BcDRWZ0pldHBnNjllS2RpT1ZlVzFNVUNxdit1bit4MnNOWStUNzFjZTZPMzRqM3FmVFpiNEVrS2haTWk2aEdhOS84U3ptM3FZRklUcDcrb0VrN2tzenNrSTZDZDVGSWd4c0UzTVc1elVlUEVoc1hvVzM3V3ZBZ1lpQjlTRGkyNHB0blk3dFg5R3JKb2VURllJZUt5Vi9mNEZSdmlSMVpjR2tTTEU3MmJqSGs4Skw4eTA4NlJvMVB3K2x6cWd2T01xVmV1YXhEd0laQ3lDZGxlbUJEZnNKdkFBNmVXSkhUdG90VDJjNS9Wc20wbEdGU2FxaWtEOWRRcGJoYzlZaG1rUVpEU1g2SU9FODUzalZOUUxuSEVsb0JHVEpLZEVMR0lRQjVOQVM4dzZ1R3kwN0JzbS9sYllsRG1OS0dWRXdnVm42bUVYN0xQTGxmSlJLdTdzR1pJUW9TRS8zUTA0b0thZUJPaTNIMzRFZ3VnNG9qWEl1SmRSU3pNUWU5U2hNQUNiNDAxY1RzYllNS1Y3anFsWFQzL3pGWG1DRkNsNmZuZG9Wb3RYT2xKVUlWQ3phSnlmY3gxUnFjZnBpTWJYUGMvUWR3RzR0MlYwcGRMY1lOaHp3dDFqd0plZHBYU2dCNlhxVWNDbVFDMTB4SFFrYTRxMWJmRFg3VVl3U3dOZVUydzQ1UjB1MHBrdGFhMXZ4SzJDNnVkU0Z2SkZjTTZSbXluOVl3T1VNbzBRRDlaamdncGRzRVhTZ3lUWENCUGFjUHR0YTBtRjhvRjM3NlZYRUpzNEhkdVVBei9VY3pJcUxZU21lMy9SdXk4aitCY1gydVJUVk9WLzM0bWVLTG1OMHNrY1BMWFQ2VlFHTWtjTFQvK0sxUFFsc0t5TWtRYXAyWnZiTHJEVjQ5UzJkY28zK1l0KzZ5V0ljN3BQdyswUVR3S3A1NGdVdVU1OEVia3hxMytuQmNSOW50M212S0pPZmtQaEZqeVE0WVhzeFlRY3dpdUZMeDJjcHZhOFMybnNxdnRKNGxNdEFsQzJaU3ZUMzJEcEs2NWZiaWR3ZXIvYWVyVTFLUjFqdkZxS3JETzN1SjMwRStKQytoVlFqTWpEanhCY2FBZCtFT0pPSFVqck1wYjFCcmRxa0FaaHMxeUhDSGJOekVMang0V2xUSW81WGM2UkpjdkxZcHhzckh3QVA2dzJLSTg3N21rNFhjUm5CRnV2dkZqOW8wT24raGZuei9HbDZzODZYdXVqSy9tWUhJZEhuYzFYRmxEek5aL3hCTWNFLzVZYXpIUEFQck1yZW1wYTVISmQ3UHRtN21ZVm90VllyT2lPc1JoWHUzRDlVU01Cck1mT2t4L21oVU9jTERXODJUaEpzQXV3aUEvTWk1cU54RURRR3dGSy9lbDF3a2Mybk5tZUgzTTVzTlRDcFVLOHllS25RdlV2ZVFyNzBWYThrYi9RcGJDelNPSEM4RTc0T0wyVWljK05qRzNBbkt0U2pvZSt3ZjE3R0FBN09SdkV6TW42ZVg3bndpZHMvR1FtYVhDVDZiQWdpMTQ5cmVWbGNZdXZUSDZpWGVyWHNkYzZKOGY1aU1NMHlpN0lralpXb1NRbTcrTnlpcFZHRUluaz08L3hlbmM6Q2lwaGVyVmFsdWU+PC94ZW5jOkNpcGhlckRhdGE+PC94ZW5jOkVuY3J5cHRlZERhdGE+PHhlbmM6RW5jcnlwdGVkS2V5IHhtbG5zOnhlbmM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jIyIgSWQ9Il8yYWVhN2E2NTFkYmI2ODc5MDJjNDgzNDMyZWQ4NTc4MCI+PHhlbmM6RW5jcnlwdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3JzYS1vYWVwLW1nZjFwIiB4bWxuczp4ZW5jPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyMiPjxkczpEaWdlc3RNZXRob2QgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3NoYTEiLz48L3hlbmM6RW5jcnlwdGlvbk1ldGhvZD48ZHM6S2V5SW5mbyB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJRXNEQ0NBcGlnQXdJQkFnSUJBREFOQmdrcWhraUc5dzBCQVFVRkFEQVRNUkV3RHdZRFZRUURFd2d4TUM0d0xqRXVOREFlRncweApOREExTURnd01EVTBNVGxhRncweE5EQTFNRGd3TURVME1UbGFNQk14RVRBUEJnTlZCQU1UQ0RFd0xqQXVNUzQwTUlJQ0lqQU5CZ2txCmhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBNWhxamFyb0pwQithUjhGTUU3aFE5bk1WMGg3TXBLdG1nRkxjSzN2d1A2N2YKZUFLK3hkdDE3aThSeVVoeGlsOUZDRlI1SzA4V2p3bzNOaUhacUhxRUtpdHcrSUpTbmRqTFNzb05nS0VJYWlGU3VnMmVWMW9ZRWx6MAo2REJYVHhjOGlxL0xhem5kcVRVb201MU9kZTl5STlBR2E4OGNETTVpT3FxOW1odUd1dnd1THRveVU3OExkK3MxRWE2TWdmN0w4TTdmClpWTzdOY3UrRmdJekk2R3QwMzVvaFlDTEJtT29NN28wdWo3RGNNRXZLT01Geml3RjQwd1lteXAzaENMbHEzcXdrTTlwVFZKbHR1ejAKQnQxdnFEZHJxM2tUaGVBOUpITWF5UnozSS9CWnhBVjNpUmQ0aHpMS1RrZWdEOFRvVEdVMTBHbWUrWkFyMXcvZXJjNWhWck0wL1hCbQpIUWxuSTVkMzFHVS9tZklrbTBYUFRHUlNwUHk3RStkVXZqOWRqdm0vVnFEZG9qZjN1dXdpckdlTE1SbE85UC9sQ2VyVGt0VzNnMjdTClY4Z24zRVRtMk1tN3JrTnFmMjRLSnBEdjB0S0Rvc2diZGFIcjJJRVlENFJwcXlTcDhrZDI1Qmh6dXNocUtSa1M4WHU1dDdIQWxWU0gKd2lGaHVMcXJyNGRVZmtCOGtaZU0veWNmWkxDbjdvTlVERmRnakdZU1ZNcGFrTDk3c0M5c2xBVzQvOFV0WFhaeExxY3lxL1l4ZHBDeQpzUFlQMWhzQXArVmdQQzdHSTZDeWlOb2pLUE9wdE1xTFpSWW5WaUt4bE9pV0JKQnpVQlJVVnVhYzhMWHJNaUR3OGJ0V0dhMUdoNXZUCmh1RlVLc3ZtUm9ldWs3ZXlYRU45SjdqNitmVFlqbnNDQXdFQUFhTVBNQTB3Q3dZRFZSMFBCQVFEQWdUd01BMEdDU3FHU0liM0RRRUIKQlFVQUE0SUNBUURBUEZVbzBQZ2E3dkI0SWp5OXUzcXBXTFFTQ2Q0eGZ3OGw5MmlxM0pxTFZYQng4R2Y5WFZ5Nkd6YlhXSWU2cG1RSQp6bW9tL0NXUXZoNm83a2MwRjR5NGZ0c1dmcW5xM2swK0hjWDRIZXUxUE4ySFNuVVVQTnNrNUFkZ2dkMzEyOU1ISWRmYUtiOGJTdUxKCnZTTWVNYXljcm1zYitnRUY2SkZQOGtHV09QNHhRWWpBVk9EY0ZiT3lBZkV1VkFodWp3MGJxbExIVCtFbDR2bGZCcnRkVStNWnp0SXEKUWtHRFc3Y21tODZaR2lCci9nYTk3QkNuT0NyZ1pYbHJnbWlhOFNtRjdSZmE0OC9Yemg3YkRtUGZnbUhnbEw1SnhocFJYMklvUFk1WApJdG1SOElhWUtoT0JPck8vcWVyY0o2WjNyUTZmSXJzOEhyWWdlVE8vdUU5d3c2V1JXQ1dEYUNSNG9XRFZ3akt6R2ZQMW9KdEFJUStVCk5qT2RkSDVvdERhd1hKUmxRV3ByNzJxVDcrV09LL3l6SmhOMHhtWERrbXQ1cHNNWS9DRG40a1hNTTB4YVJwZllPbjVTYzFvZWxRK2gKSW04L3JIVksvMGtyaENET25pcWorTC9uZTJTb3lvWFlnUzZvME5sa05odFRIbWpqb3NFN0hWNkpmQVVncTJEOWRxMDBKTzk2N0kzUAowVkY2RjhsY2RhcTB0b3ZKaEtXUmpycmlnWWQ3NTYvM2FUMkI4M0pXQTFSQTluaVhtclhmbkFQWnJOQ2ZXdmorWDJhbFVOL2l6ZElxClJ0czBVcFdUb1ZVcjBveldnbWJtcDVaT0dZT1FoK2xOY0FwM1Y5bE9yZGJaVlNJVE00N1JZR0JaYVpOREEyUGJEekMxM01TL0VqVEUKdlNrb253dGxDZz09PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PHhlbmM6Q2lwaGVyRGF0YSB4bWxuczp4ZW5jPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyMiPjx4ZW5jOkNpcGhlclZhbHVlPm4wR3IzSWtSSWRjaDZRVHhsTDJRWkNuUVBGM3R4T0hHbXpSLytObzExUlRSZjYrczBYUGxvK0RqYVd1RVdwMkh0MldkRm5UdXM5RmJwSGF0UVdiSVI1SVdUQXFrN3ZXSWlhTW0wV3prRnVPR1hrYi82ckV4cUdOYnY4UTlJUHVMZW85VVNOOWNrZTF5RFlFK2F2NngyU1ZzUjMydHJINXBCV1VyYkNCV0pGNWwyVXRHVlNwWEVwdUFWenppUVhDWTBycXltdmZSVmFGbGhWMVMyb2RXVW1LZU5YL1ZKNXJuME5adE5Zdlo1ZXFhWWJjNnpUQ2sxMEVkUjB6czV6UDFmQmxYMmtDVE8zdlZqNWhHKzV5TUdvRFR3OWxYWXBZUDNtUVpERHFlU2hDcnNKeitPNjNpU0oxZkdqdndhSWZ5QTB4ditON2MrR3I1Zlh1UzR0clozcU9GYkx5TStNS3NWVUNJNG1wTmZsUHRYNjEvSm1NRXFBZFNreFRadFZtY3NDbDZyNlVoSVlVM2ZEOS9JaGFWZDZtSFVvMVJ5WGVnOTlZNTVBMzl6VVVtNWViNzFsVC9qZjduV0p1ZWI1SWZIa1hMQ0ExVldBZGllV2hTbHNtKzBUd1ZKRE5TYTlocUYwb1ZLL0FLcTZEV202ZStVUmVyazF5NFJscDZQa2owb1hBclJ4dkJFTTJXT0VBQWJxdndyeldtSlIwZ2lnQTdVMHB4YnpGcmRoNzdzOVZuRkFQc1Q2aDZ6WmYrbWt1d1JIQUh4Zmk1dURzU1c3RWw3cVdmMjh1dnhKeXUxL0FjbVNHNDRxSk0xelZhSlQyVmU2bXZFYktOWVJ6K2FCZzVNSG1hcWdjQm82VTd3Uk16bHVPNGlSbjVJSVZ1eDlGRTY5eUVhbWliTFNVPTwveGVuYzpDaXBoZXJWYWx1ZT48L3hlbmM6Q2lwaGVyRGF0YT48eGVuYzpSZWZlcmVuY2VMaXN0Pjx4ZW5jOkRhdGFSZWZlcmVuY2UgVVJJPSIjXzllOGZkMmNlNGFkMDIxMmM5OGU3MDkxY2E4NzY1ZmI0Ii8+PC94ZW5jOlJlZmVyZW5jZUxpc3Q+PC94ZW5jOkVuY3J5cHRlZEtleT48L3NhbWwyOkVuY3J5cHRlZEFzc2VydGlvbj48L3NhbWwycDpSZXNwb25zZT4=', + RelayState: '', + }, + config: { + entryPoint: 'https://frontapp.oktapreview.com/app/frontdev584714_front_1/exk7xdi6axPfombzx0h7/sso/saml', + cert: 'MIIDoDCCAoigAwIBAgIGAVaZ04POMA0GCSqGSIb3DQEBBQUAMIGQMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxETAPBgNVBAMMCGZyb250YXBwMRwwGgYJKoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMB4XDTE2MDgxNzE4NDUzMVoXDTI2MDgxNzE4NDYzMVowgZAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARPa3RhMRQwEgYDVQQLDAtTU09Qcm92aWRlcjERMA8GA1UEAwwIZnJvbnRhcHAxHDAaBgkqhkiG9w0BCQEWDWluZm9Ab2t0YS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvplQONVwknRy1iBnaoZtsOz28A7XW2tRpFW+0La7RJexbziIwEy1bPZENhfwjPZA1oHHZqi5l315BxXKWJqmmNmbDCFDo+/FYFCoHXliiLm9vqDbR1br6ByqeY0GfxyTPKHZxb2FSes30TffDknpMQd/8kA9YWaW5xDlu2ivWJI+sfcOJOMd6t+gcfXj58a5fP8Mwm6Y220KeZSvrVpEV2KDp9hln7fhhoxHZ7K/BYbidqdwLzeUQXpb6LIrxtKdug2FofS+ONs6yLIQRmrbCB7SVX1QA8JInMn+fzrGtZmFiHR0aFbyhiO78v/ufDa6S+XpYyp2b6D4SnzeggnobAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAJ2wcFVffFHSd9pj6RgoNHXZBsWp0HUZrNekiSbgomr4tSDefWtKb04nFIlRytfVs/k74wmbNiRCE8nDVBrBDFA/+Tv/3PowZXHjXKBofUuScTP4/Tw1N/ywf7V+XY5kV3VmLBL6ax+ULJauR/YGIIMsIc/rS2D04aAcScU9pqVh2ML7nTH7gFqYrxypavmVk6K94vLjs0ggF2TGp7tXCRjeOlPPJS+MOJHJhTBWYFWvBLclU3zcri3ws7GqJMpeiHa7rMoHV0onxWsZTZW57ybaIWKLt1goAooC7hq0rx7oNlOvrys5lllhBySYYC3ycqca/D0+GxXLcEr9QwP7TVw=', + decryptionPvk: fs.readFileSync(__dirname + '/static/testshib encryption pvk.pem') + }, + expectedStatusCode: 200, + expectedNameIDStartsWith: 'xavier', + mockDate: '2016-08-19T01:15:32.681Z' + }, { name: 'Onelogin -- invalid cert (from Okta case) should fail', samlResponse: { SAMLResponse: 'PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0\r\nYzpTQU1MOjIuMDphc3NlcnRpb24iIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6\r\nbmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIElEPSJSNjg5YjA3MzNiY2Nj\r\nYTIyYTEzN2UzNjU0ODMwMzEyMzMyOTQwYjFiZSIgVmVyc2lvbj0iMi4wIiBJ\r\nc3N1ZUluc3RhbnQ9IjIwMTQtMDUtMjhUMDA6MTY6MDhaIiBEZXN0aW5hdGlv\r\nbj0ie3JlY2lwaWVudH0iIEluUmVzcG9uc2VUbz0iX2E2ZmM0NmJlODRlMWUz\r\nY2YzYzUwIj48c2FtbDpJc3N1ZXI+aHR0cHM6Ly9hcHAub25lbG9naW4uY29t\r\nL3NhbWwvbWV0YWRhdGEvMzcxNzU1PC9zYW1sOklzc3Vlcj48c2FtbHA6U3Rh\r\ndHVzPjxzYW1scDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6\r\ndGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz48L3NhbWxwOlN0YXR1cz48\r\nc2FtbDpBc3NlcnRpb24geG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIw\r\nMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIw\r\nMDEvWE1MU2NoZW1hLWluc3RhbmNlIiBWZXJzaW9uPSIyLjAiIElEPSJwZngz\r\nYjYzYzdiZS1mZTg2LTYyZmQtOGNiNS0xNmFiNjI3M2VmYWEiIElzc3VlSW5z\r\ndGFudD0iMjAxNC0wNS0yOFQwMDoxNjowOFoiPjxzYW1sOklzc3Vlcj5odHRw\r\nczovL2FwcC5vbmVsb2dpbi5jb20vc2FtbC9tZXRhZGF0YS8zNzE3NTU8L3Nh\r\nbWw6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cu\r\ndzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxkczpTaWduZWRJbmZvPjxkczpD\r\nYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53\r\nMy5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PGRzOlNpZ25hdHVyZU1l\r\ndGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1s\r\nZHNpZyNyc2Etc2hhMSIvPjxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4M2I2M2M3\r\nYmUtZmU4Ni02MmZkLThjYjUtMTZhYjYyNzNlZmFhIj48ZHM6VHJhbnNmb3Jt\r\ncz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcv\r\nMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJh\r\nbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94\r\nbWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRo\r\nb2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRz\r\naWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT5EQ25QVFFZQmIxaEtzcGJlNmZn\r\nMVUzcTh4bjQ9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2Rz\r\nOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPmUwK2FGb21BMCtKQVkw\r\nZjl0S3F6SXVxSVZTU3c3TGlGVXNuZUVES1BCV2RpVHoxc01kZ3IvMnkxZTkr\r\ncmphUzJtUm1DaS92U1FMWTN6VFl6MGhwNm5KTlUxOStUV29YbzlrSFF5V1Q0\r\nS2tlUUw0WHMvZ1ovQW9LQzIwaUhWS3RwUHBzMElRME1sL3FSb291U2l0dDZT\r\nZi9XRHoyTFYvcFdjSDJoeDV0djN4U3czNmhLMk5RYzdxdzdyMW1FWG52Y2pY\r\nUmVZbzhyclZmN1hIR0d4Tm9SSUVJQ1VJaTExMHV2c1dlbVNYZjBaMGR5YjBG\r\nVllPV3VTc1FNRGx6TnBoZUFEQmlmRk80VVRmU0VoRlp2bjhrVkNHWlVJd3Ji\r\nT2haMmQvK1lFdGd5dVRnK3F0c2xnZnk0ZHdkNFR2RWNmdVJ6UVRhemVlZnBy\r\nU0Z5aVFja0FYT2pjdz09PC9kczpTaWduYXR1cmVWYWx1ZT48ZHM6S2V5SW5m\r\nbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlFRnpDQ0F2\r\nK2dBd0lCQWdJVUZKc1VqUE03QW1Xdk50RXZVTFNIbFRUTWlMUXdEUVlKS29a\r\nSWh2Y05BUUVGQlFBd1dERUxNQWtHQTFVRUJoTUNWVk14RVRBUEJnTlZCQW9N\r\nQ0ZOMVluTndZV05sTVJVd0V3WURWUVFMREF4UGJtVk1iMmRwYmlCSlpGQXhI\r\nekFkQmdOVkJBTU1Gazl1WlV4dloybHVJRUZqWTI5MWJuUWdOREl6TkRrd0ho\r\nY05NVFF3TlRFek1UZ3dOakV5V2hjTk1Ua3dOVEUwTVRnd05qRXlXakJZTVFz\r\nd0NRWURWUVFHRXdKVlV6RVJNQThHQTFVRUNnd0lVM1ZpYzNCaFkyVXhGVEFU\r\nQmdOVkJBc01ERTl1WlV4dloybHVJRWxrVURFZk1CMEdBMVVFQXd3V1QyNWxU\r\nRzluYVc0Z1FXTmpiM1Z1ZENBME1qTTBPVENDQVNJd0RRWUpLb1pJaHZjTkFR\r\nRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFLckF6SmRZOUZ6Rkx0NWJsQXJKZlB6\r\nZ2k4N0VuRkdsVGZjVjVUMVRVRHdMQmxEa1kvMFpHS25NT3BmM0Q3aWUyQzRw\r\nUEZPSW1Pb2djTTVrcERETDdxeFRYWjFld1hWeWpCZE11MjlORzJDNk56V2VR\r\nVFVNVWppMDFFY0hrQzhvK1B0czhBTmlOT1ljanhFZXloRXl6SktnRWl6YmxZ\r\nek1NS3pkck9FVDZRdXFXbzNDODNLKzUrNWRzakRuMW9vS0dSd2ozSHZnc1lj\r\nRnJRbDlOb2pnUUZqb29id3NpRS83QStPSmhMcEJjeS9uU1Znbm9KYU1mck8r\r\nSnNudWtaUHp0Ym50THZPbDU2K1ZyYTBOOG41TkFZaGFTYXlQaXYvYXloalZn\r\namZYZDF0ak1WVE9pRGtuVU93aXpadUoxWTNRSDk0dlV0QmdwMFdCcEJTcy94\r\nTXlUczhDQXdFQUFhT0IyRENCMVRBTUJnTlZIUk1CQWY4RUFqQUFNQjBHQTFV\r\nZERnUVdCQlJRTzRXcE01Zld3eGliNDlXVHVKa2ZZRGJ4T0RDQmxRWURWUjBq\r\nQklHTk1JR0tnQlJRTzRXcE01Zld3eGliNDlXVHVKa2ZZRGJ4T0tGY3BGb3dX\r\nREVMTUFrR0ExVUVCaE1DVlZNeEVUQVBCZ05WQkFvTUNGTjFZbk53WVdObE1S\r\nVXdFd1lEVlFRTERBeFBibVZNYjJkcGJpQkpaRkF4SHpBZEJnTlZCQU1NRms5\r\ndVpVeHZaMmx1SUVGalkyOTFiblFnTkRJek5EbUNGQlNiRkl6ek93SmxyemJS\r\nTDFDMGg1VTB6SWkwTUE0R0ExVWREd0VCL3dRRUF3SUhnREFOQmdrcWhraUc5\r\ndzBCQVFVRkFBT0NBUUVBQ2REQUFvYVpGQ0VZNXBtZndiS3VLclh0TzVpRThs\r\nV3RpQ1BqQ1pFVXVUNmJYUk5jcXJkbnVWL0VBZlg5V1FvWGphbFBpMGVNNzh6\r\nS21idlJHU1RVSHdXdzQ5UkhqRmZlSlVLdkhOZU5uRmdUWERqRVBOaE12aDY5\r\na0htNDUzbEZSbUIra2s2eWp0WFJaYVFFd1M4VXVvMk90K2tyZ05ibDZvVEJa\r\nSjBBSEgxTXRaRUNEbG9tczFLbTd6c0s4d0FpNWk4VFZJS2tWcjViMlZsaHJM\r\nZ0ZNdnpaNVZpQXhJTUdCNnc0N3lZNFFHUUIvNVE4eWE5aEJzOXZrbit3dWJB\r\nK3lyNGoxNEpYWjdibFZLRFNUWXZhNjVFYStQcUh5cnArV25tbmJ3Mk9iUzdp\r\nV2V4aVR5MWpEM0cwUjJhdkRCRmpNOEZqNURiZnVmc0UxYjBVMTBSVHRnPT08\r\nL2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5m\r\nbz48L2RzOlNpZ25hdHVyZT48c2FtbDpTdWJqZWN0PjxzYW1sOk5hbWVJRCBG\r\nb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpuYW1laWQtZm9y\r\nbWF0OnRyYW5zaWVudCI+cGxvZXJAc3Vic3BhY2Vzdy5jb208L3NhbWw6TmFt\r\nZUlEPjxzYW1sOlN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2Fz\r\naXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj48c2FtbDpTdWJqZWN0\r\nQ29uZmlybWF0aW9uRGF0YSBOb3RPbk9yQWZ0ZXI9IjIwMTQtMDUtMjhUMDA6\r\nMTk6MDhaIiBSZWNpcGllbnQ9IntyZWNpcGllbnR9IiBJblJlc3BvbnNlVG89\r\nIl9hNmZjNDZiZTg0ZTFlM2NmM2M1MCIvPjwvc2FtbDpTdWJqZWN0Q29uZmly\r\nbWF0aW9uPjwvc2FtbDpTdWJqZWN0PjxzYW1sOkNvbmRpdGlvbnMgTm90QmVm\r\nb3JlPSIyMDE0LTA1LTI4VDAwOjEzOjA4WiIgTm90T25PckFmdGVyPSIyMDE0\r\nLTA1LTI4VDAwOjE5OjA4WiI+PHNhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj48\r\nc2FtbDpBdWRpZW5jZT57YXVkaWVuY2V9PC9zYW1sOkF1ZGllbmNlPjwvc2Ft\r\nbDpBdWRpZW5jZVJlc3RyaWN0aW9uPjwvc2FtbDpDb25kaXRpb25zPjxzYW1s\r\nOkF1dGhuU3RhdGVtZW50IEF1dGhuSW5zdGFudD0iMjAxNC0wNS0yOFQwMDox\r\nNjowN1oiIFNlc3Npb25Ob3RPbk9yQWZ0ZXI9IjIwMTQtMDUtMjlUMDA6MTY6\r\nMDhaIiBTZXNzaW9uSW5kZXg9Il8zMGE0YWY1MC1jODJiLTAxMzEtZjhiNS03\r\nODJiY2I1NmZjYWEiPjxzYW1sOkF1dGhuQ29udGV4dD48c2FtbDpBdXRobkNv\r\nbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6\r\nY2xhc3NlczpQYXNzd29yZFByb3RlY3RlZFRyYW5zcG9ydDwvc2FtbDpBdXRo\r\nbkNvbnRleHRDbGFzc1JlZj48L3NhbWw6QXV0aG5Db250ZXh0Pjwvc2FtbDpB\r\ndXRoblN0YXRlbWVudD48L3NhbWw6QXNzZXJ0aW9uPjwvc2FtbHA6UmVzcG9u\r\nc2U+Cgo=\r\n' @@ -165,7 +179,7 @@ describe( 'passport-saml /', function() { should.exist(passedRequest); passedRequest.url.should.eql('/login'); passedRequest.method.should.eql('POST'); - passedRequest.body.should.eql(check.samlResponse); + should(passedRequest.body).match(check.samlResponse); } else { should.not.exist(passedRequest); } @@ -193,52 +207,52 @@ describe( 'passport-saml /', function() { { name: "Empty Config", config: {}, result: { - 'samlp:AuthnRequest': - { '$': + 'samlp:AuthnRequest': + { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Version: '2.0', ProtocolBinding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', AssertionConsumerServiceURL: 'http://localhost:3033/login', Destination: 'https://wwwexampleIdp.com/saml'}, - 'saml:Issuer': + 'saml:Issuer': [ { _: 'onelogin_saml', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ], - 'samlp:NameIDPolicy': - [ { '$': + 'samlp:NameIDPolicy': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Format: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', AllowCreate: 'true' } } ], - 'samlp:RequestedAuthnContext': - [ { '$': + 'samlp:RequestedAuthnContext': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Comparison: 'exact' }, - 'saml:AuthnContextClassRef': + 'saml:AuthnContextClassRef': [ { _: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ] } ] } } }, { name: "Empty Config w/ HTTP-POST binding", config: { authnRequestBinding: 'HTTP-POST' }, result: { - 'samlp:AuthnRequest': - { '$': + 'samlp:AuthnRequest': + { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Version: '2.0', ProtocolBinding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', AssertionConsumerServiceURL: 'http://localhost:3033/login', Destination: 'https://wwwexampleIdp.com/saml'}, - 'saml:Issuer': + 'saml:Issuer': [ { _: 'onelogin_saml', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ], - 'samlp:NameIDPolicy': - [ { '$': + 'samlp:NameIDPolicy': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Format: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', AllowCreate: 'true' } } ], - 'samlp:RequestedAuthnContext': - [ { '$': + 'samlp:RequestedAuthnContext': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Comparison: 'exact' }, - 'saml:AuthnContextClassRef': + 'saml:AuthnContextClassRef': [ { _: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ] } ] } } }, @@ -250,9 +264,9 @@ describe( 'passport-saml /', function() { attributeConsumingServiceIndex: 123, forceAuthn: false }, - result: { - 'samlp:AuthnRequest': - { '$': + result: { + 'samlp:AuthnRequest': + { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Version: '2.0', ProtocolBinding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', @@ -260,19 +274,19 @@ describe( 'passport-saml /', function() { AttributeConsumingServiceIndex: '123', Destination: 'https://wwwexampleIdp.com/saml', IsPassive: 'true'}, - 'saml:Issuer': + 'saml:Issuer': [ { _: 'http://exampleSp.com/saml', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ], - 'samlp:NameIDPolicy': - [ { '$': + 'samlp:NameIDPolicy': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Format: 'alternateIdentifier', AllowCreate: 'true' } } ], - 'samlp:RequestedAuthnContext': - [ { '$': + 'samlp:RequestedAuthnContext': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Comparison: 'exact' }, - 'saml:AuthnContextClassRef': + 'saml:AuthnContextClassRef': [ { _: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ] } ] } } }, @@ -284,9 +298,9 @@ describe( 'passport-saml /', function() { attributeConsumingServiceIndex: 123, skipRequestCompression: true }, - result: { - 'samlp:AuthnRequest': - { '$': + result: { + 'samlp:AuthnRequest': + { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Version: '2.0', ProtocolBinding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', @@ -294,19 +308,19 @@ describe( 'passport-saml /', function() { AttributeConsumingServiceIndex: '123', Destination: 'https://wwwexampleIdp.com/saml', IsPassive: 'true' }, - 'saml:Issuer': + 'saml:Issuer': [ { _: 'http://exampleSp.com/saml', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ], - 'samlp:NameIDPolicy': - [ { '$': + 'samlp:NameIDPolicy': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Format: 'alternateIdentifier', AllowCreate: 'true' } } ], - 'samlp:RequestedAuthnContext': - [ { '$': + 'samlp:RequestedAuthnContext': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Comparison: 'exact' }, - 'saml:AuthnContextClassRef': + 'saml:AuthnContextClassRef': [ { _: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ] } ] } } }, @@ -320,9 +334,9 @@ describe( 'passport-saml /', function() { disableRequestedAuthnContext: true, forceAuthn: true }, - result: { - 'samlp:AuthnRequest': - { '$': + result: { + 'samlp:AuthnRequest': + { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Version: '2.0', ProtocolBinding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', @@ -331,11 +345,11 @@ describe( 'passport-saml /', function() { Destination: 'https://wwwexampleIdp.com/saml', IsPassive: 'true', ForceAuthn: 'true' }, - 'saml:Issuer': + 'saml:Issuer': [ { _: 'http://exampleSp.com/saml', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ], - 'samlp:NameIDPolicy': - [ { '$': + 'samlp:NameIDPolicy': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Format: 'alternateIdentifier', AllowCreate: 'true' } } ] } } @@ -348,9 +362,9 @@ describe( 'passport-saml /', function() { attributeConsumingServiceIndex: 123, authnContext: 'myAuthnContext' }, - result: { - 'samlp:AuthnRequest': - { '$': + result: { + 'samlp:AuthnRequest': + { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Version: '2.0', ProtocolBinding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', @@ -358,19 +372,19 @@ describe( 'passport-saml /', function() { AttributeConsumingServiceIndex: '123', Destination: 'https://wwwexampleIdp.com/saml', IsPassive: 'true'}, - 'saml:Issuer': + 'saml:Issuer': [ { _: 'http://exampleSp.com/saml', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ], - 'samlp:NameIDPolicy': - [ { '$': + 'samlp:NameIDPolicy': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Format: 'alternateIdentifier', AllowCreate: 'true' } } ], - 'samlp:RequestedAuthnContext': - [ { '$': + 'samlp:RequestedAuthnContext': + [ { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', Comparison: 'exact' }, - 'saml:AuthnContextClassRef': + 'saml:AuthnContextClassRef': [ { _: 'myAuthnContext', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ] } ] } } } @@ -393,7 +407,7 @@ describe( 'passport-saml /', function() { }) ); - app.get( '/login', + app.get( '/login', passport.authenticate( "saml", { samlFallback: 'login-request', session: false } ), function(req, res) { res.status(200).send("200 OK"); @@ -458,16 +472,16 @@ describe( 'passport-saml /', function() { describe( 'saml.js / ', function() { it( 'generateLogoutRequest', function( done ) { - var expectedRequest = { - 'samlp:LogoutRequest': - { '$': + 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': + 'saml:Issuer': [ { _: 'onelogin_saml', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ], 'saml:NameID': [ { _: 'bar', '$': { Format: 'foo' } } ] } }; @@ -488,16 +502,16 @@ describe( 'passport-saml /', function() { }); it( 'generateLogoutRequest adds the NameQualifier and SPNameQualifier to the saml request', function( done ) { - var expectedRequest = { - 'samlp:LogoutRequest': - { '$': + 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': + 'saml:Issuer': [ { _: 'onelogin_saml', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ], 'saml:NameID': [ { _: 'bar', '$': { Format: 'foo', @@ -522,9 +536,9 @@ describe( 'passport-saml /', function() { }); it( 'generateLogoutResponse', function( done ) { - var expectedResponse = { - 'samlp:LogoutResponse': - { '$': + var expectedResponse = { + 'samlp:LogoutResponse': + { '$': { 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion', //ID: '_d11b3c5e085b2417f4aa', @@ -546,21 +560,21 @@ describe( 'passport-saml /', function() { }); it( 'generateLogoutRequest', function( done ) { - var expectedRequest = { - 'samlp:LogoutRequest': - { '$': + 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': + 'saml:Issuer': [ { _: 'onelogin_saml', '$': { 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion' } } ], 'saml:NameID': [ { _: 'bar', '$': { Format: 'foo' } } ], - 'saml2p:SessionIndex': - [ { _: 'session-id', + 'saml2p:SessionIndex': + [ { _: 'session-id', '$': { 'xmlns:saml2p': 'urn:oasis:names:tc:SAML:2.0:protocol' } } ] } }; var samlObj = new SAML( { entryPoint: "foo" } ); @@ -722,7 +736,7 @@ describe( 'passport-saml /', function() { }); it('accept response with an attributeStatement element without attributeValue', function(done) { - var container = { + var container = { SAMLResponse : fs.readFileSync( __dirname + '/static/response-with-uncomplete-attribute.xml' ).toString('base64')