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, '&lt;')
       .replace(/>/g, '&gt;')
-       // 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')