passport-saml-encrypted
Advanced tools
Comparing version 0.0.4 to 0.1.0
@@ -48,3 +48,3 @@ var zlib = require('zlib'); | ||
var date = new Date(); | ||
return date.getUTCFullYear() + '-' + ('0' + (date.getUTCMonth()+1)).slice(-2) + '-' + ('0' + date.getUTCDate()).slice(-2) + 'T' + ('0' + (date.getUTCHours()+2)).slice(-2) + ":" + ('0' + date.getUTCMinutes()).slice(-2) + ":" + ('0' + date.getUTCSeconds()).slice(-2) + "Z"; | ||
return date.getUTCFullYear() + '-' + ('0' + (date.getUTCMonth()+1)).slice(-2) + '-' + ('0' + date.getUTCDate()).slice(-2) + 'T' + ('0' + (date.getUTCHours()+2)).slice(-2) + ":" + ('0' + date.getUTCMinutes()).slice(-2) + ":" + ('0' + date.getUTCSeconds()).slice(-2) + "Z"; | ||
}; | ||
@@ -56,3 +56,3 @@ */ | ||
return new Date().toISOString(); | ||
}; | ||
}; | ||
@@ -77,4 +77,4 @@ SAML.prototype.signRequest = function (xml) { | ||
var request = | ||
"<samlp:AuthnRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"" + id + "\" Version=\"2.0\" IssueInstant=\"" + instant + | ||
"\" ProtocolBinding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" AssertionConsumerServiceURL=\"" + callbackUrl + "\" Destination=\"" + | ||
"<samlp:AuthnRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"" + id + "\" Version=\"2.0\" IssueInstant=\"" + instant + | ||
"\" ProtocolBinding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" AssertionConsumerServiceURL=\"" + callbackUrl + "\" Destination=\"" + | ||
this.options.entryPoint + "\">" + | ||
@@ -84,7 +84,7 @@ "<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">" + this.options.issuer + "</saml:Issuer>\n"; | ||
if (this.options.identifierFormat) { | ||
request += "<samlp:NameIDPolicy xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" Format=\"" + this.options.identifierFormat + | ||
request += "<samlp:NameIDPolicy xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" Format=\"" + this.options.identifierFormat + | ||
"\" AllowCreate=\"true\"></samlp:NameIDPolicy>\n"; | ||
} | ||
/* request += | ||
/* request += | ||
"<samlp:RequestedAuthnContext xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" Comparison=\"exact\">" + | ||
@@ -103,5 +103,5 @@ "<saml:AuthnContextClassRef xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef></samlp:RequestedAuthnContext>\n" + | ||
//samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" | ||
// ID="_135ad2fd-b275-4428-b5d6-3ac3361c3a7f" Version="2.0" Destination="https://idphost/adfs/ls/" | ||
//IssueInstant="2008-06-03T12:59:57Z"><saml:Issuer>myhost</saml:Issuer><NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" | ||
//samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" | ||
// ID="_135ad2fd-b275-4428-b5d6-3ac3361c3a7f" Version="2.0" Destination="https://idphost/adfs/ls/" | ||
//IssueInstant="2008-06-03T12:59:57Z"><saml:Issuer>myhost</saml:Issuer><NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" | ||
//NameQualifier="https://idphost/adfs/ls/">myemail@mydomain.com</NameID<samlp:SessionIndex>_0628125f-7f95-42cc-ad8e-fde86ae90bbe | ||
@@ -132,5 +132,5 @@ //</samlp:SessionIndex></samlp:LogoutRequest> | ||
target = self.options.logoutUrl + '?'; | ||
} | ||
} | ||
} | ||
var samlRequest = { | ||
@@ -152,3 +152,3 @@ SAMLRequest: base64 | ||
var request = this.generateAuthorizeRequest(req); | ||
this.requestToUrl(request, 'authorize', callback); | ||
@@ -171,4 +171,4 @@ }; | ||
SAML.prototype.checkSAMLStatus = function (xmlDomDoc) { | ||
var status = {StatusCodeValue:null, StatusMessage:null, StatusDetail:null} | ||
var status = {StatusCodeValue:null, StatusMessage:null, StatusDetail:null} | ||
var statusCodeValueNode = xmlCrypto.xpath(xmlDomDoc, "//*[local-name(.)='StatusCode']")[0]; | ||
@@ -179,3 +179,3 @@ if(statusCodeValueNode) | ||
} | ||
var statusMessageNode = xmlCrypto.xpath(xmlDomDoc, "//*[local-name(.)='StatusMessage']")[0]; | ||
@@ -186,4 +186,4 @@ if(statusMessageNode) | ||
} | ||
var statusDetailNode = xmlCrypto.xpath(xmlDomDoc, "//*[local-name(.)='StatusDetail']/*[local-name(.)='Cause']")[0]; | ||
var statusDetailNode = xmlCrypto.xpath(xmlDomDoc, "//*[local-name(.)='StatusDetail']/*[local-name(.)='Cause']")[0]; | ||
if(statusDetailNode) | ||
@@ -194,3 +194,3 @@ { | ||
//status.StatusMessage = xmlCrypto.xpath(xmlDomDoc, "//*[local-name(.)='StatusMessage']")[0].childNodes[0].nodeValue; | ||
//status.StatusDetail = xmlCrypto.xpath(xmlDomDoc, "//*[local-name(.)='StatusDetail']/*[local-name(.)='Cause']")[0].childNodes[0].nodeValue; | ||
//status.StatusDetail = xmlCrypto.xpath(xmlDomDoc, "//*[local-name(.)='StatusDetail']/*[local-name(.)='Cause']")[0].childNodes[0].nodeValue; | ||
return status; | ||
@@ -203,5 +203,5 @@ }; | ||
//console.log(encryptedData); | ||
var decryptOptions = { key: privateCert }; | ||
var decryptOptions = { key: privateCert }; | ||
var resultObj = decryptSAML(encryptedData,decryptOptions); | ||
if(resultObj.result) | ||
if(resultObj.result) | ||
{ | ||
@@ -212,3 +212,3 @@ return resultObj.result; | ||
{ | ||
return resultObj.err; | ||
return resultObj.err; | ||
} | ||
@@ -239,3 +239,3 @@ }; | ||
return parentElement['samlp:'+elementName]; | ||
} | ||
} | ||
return parentElement[elementName]; | ||
@@ -246,5 +246,5 @@ } | ||
var self = this; | ||
var xml = new Buffer(samlResponse, 'base64').toString('ascii'); | ||
var samlAssertion = null; | ||
var xml = new Buffer(samlResponse, 'base64').toString(); | ||
var samlAssertion = null; | ||
// Verify signature on the response | ||
@@ -254,3 +254,3 @@ if (self.options.cert && !self.validateSignature(xml, self.options.cert)) { | ||
} | ||
var xmlDomDoc = new xmldom.DOMParser().parseFromString(xml); | ||
@@ -261,7 +261,7 @@ //Check Status code in the SAML Response | ||
return callback(new Error('SAML Error Response:\nStatusCodeValue = '+ statusObj.StatusCodeValue + '\nStatusMessage = ' + statusObj.StatusMessage + '\nStatusDetail = ' + statusObj.StatusDetail + '\n'), null, false); | ||
// Decrypt and Retrieve SAML Assertion | ||
// Decrypt and Retrieve SAML Assertion | ||
if (self.options.encryptedSAML && self.options.privateCert) | ||
{ | ||
samlAssertion = self.decryptSAMLAssertion(xmlDomDoc, self.options.privateCert); | ||
samlAssertion = self.decryptSAMLAssertion(xmlDomDoc, self.options.privateCert); | ||
if (!samlAssertion){ | ||
@@ -282,7 +282,7 @@ return callback(new Error('Decryption Failed'), null, false); | ||
} | ||
else //Retrieve SAML Assertion | ||
else //Retrieve SAML Assertion | ||
{ | ||
samlAssertionNode = xmlCrypto.xpath(xmlDomDoc, "//*[local-name(.)='Assertion']")[0]; | ||
if (samlAssertionNode) | ||
{ | ||
{ | ||
samlAssertion = samlAssertionNode.toString(); | ||
@@ -294,9 +294,9 @@ } | ||
} | ||
} | ||
} | ||
var parser = new xml2js.Parser({explicitRoot:true}); | ||
parser.parseString(samlAssertion, function (err, doc) { | ||
parser.parseString(samlAssertion, function (err, doc) { | ||
var assertion = self.getElement(doc, 'Assertion'); | ||
if (assertion) { | ||
@@ -336,12 +336,15 @@ /* | ||
attributes.forEach(function (attribute) { | ||
var value = self.getElement(attribute, 'AttributeValue'); | ||
if (typeof value[0] === 'string') { | ||
profile[attribute['$'].Name] = value[0]; | ||
} else { | ||
profile[attribute['$'].Name] = value[0]['_']; | ||
} | ||
var attributeValues = self.getElement(attribute, 'AttributeValue'); | ||
//Extract the text of all the values for this attribute into an array. | ||
var textValues = attributeValues.map(function (value) { | ||
return (typeof value === 'string') ? value : value['_']; | ||
}); | ||
//If it's only one entry, append it directly. Otherwise pass the array. | ||
profile[attribute['$'].Name] = (textValues.length === 1) ? textValues[0] : textValues; | ||
}); | ||
} | ||
if (!profile.mail && profile['urn:oid:0.9.2342.19200300.100.1.3']) { | ||
@@ -348,0 +351,0 @@ // See http://www.incommonfederation.org/attributesummary.html for definition of attribute OIDs |
{ | ||
"name": "passport-saml-encrypted", | ||
"version": "0.0.4", | ||
"version": "0.1.0", | ||
"description": "A Passport strategy for handling encrypted SAML authentication responses", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -11,2 +11,17 @@ passport-saml-encrypted | ||
### Returned data object: | ||
**Note**: If there is a single value for an attribute, it will be a string. If there are multiple values, it will be an array. E.G.: | ||
```json | ||
{ issuer: 'https://fedpocv1.corp.company.com', | ||
nameID: 'g2IpU4vJ53211ila09gh8wUtzgm', | ||
nameIDFormat: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', | ||
Email: ' lmarkus@company.com', | ||
Corpid: 'lmarkus', | ||
FirstName: 'Lenny', | ||
LastName: 'Markus', | ||
ROLE_NAME: [ 'R_DEFAULT_ADMINISTRATION_ROLE', 'V_V_OPERATIONS' ] } | ||
``` | ||
Contributions welcome. | ||
@@ -13,0 +28,0 @@ |
22375
406
136