passport-saml-restify
Advanced tools
Comparing version 1.0.4 to 1.0.5
@@ -30,6 +30,2 @@ var zlib = require('zlib'); | ||
if (!options.host) { | ||
options.host = 'localhost'; | ||
} | ||
if (!options.issuer) { | ||
@@ -70,29 +66,5 @@ options.issuer = 'onelogin_saml'; | ||
// sha1 or sha256 | ||
if (!options.signatureAlgorithm) { | ||
options.signatureAlgorithm = 'sha1'; | ||
} | ||
return options; | ||
}; | ||
SAML.prototype.getProtocol = function (req) { | ||
return this.options.protocol || (req.protocol || 'http').concat('://'); | ||
}; | ||
SAML.prototype.getCallbackUrl = function (req) { | ||
// Post-auth destination | ||
if (this.options.callbackUrl) { | ||
return this.options.callbackUrl; | ||
} else { | ||
var host; | ||
if (req.headers) { | ||
host = req.headers.host; | ||
} else { | ||
host = this.options.host; | ||
} | ||
return this.getProtocol(req) + host + this.options.path; | ||
} | ||
}; | ||
SAML.prototype.generateUniqueID = function () { | ||
@@ -111,29 +83,6 @@ var chars = "abcdef0123456789"; | ||
SAML.prototype.signRequest = function (samlMessage) { | ||
var signer; | ||
var samlMessageToSign = {}; | ||
switch(this.options.signatureAlgorithm) { | ||
case 'sha256': | ||
samlMessage.SigAlg = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; | ||
signer = crypto.createSign('RSA-SHA256'); | ||
break; | ||
default: | ||
samlMessage.SigAlg = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'; | ||
signer = crypto.createSign('RSA-SHA1'); | ||
break; | ||
} | ||
if (samlMessage.SAMLRequest) { | ||
samlMessageToSign.SAMLRequest = samlMessage.SAMLRequest; | ||
} | ||
if (samlMessage.SAMLResponse) { | ||
samlMessageToSign.SAMLResponse = samlMessage.SAMLResponse; | ||
} | ||
if (samlMessage.RelayState) { | ||
samlMessageToSign.RelayState = samlMessage.RelayState; | ||
} | ||
if (samlMessage.SigAlg) { | ||
samlMessageToSign.SigAlg = samlMessage.SigAlg; | ||
} | ||
signer.update(querystring.stringify(samlMessageToSign)); | ||
samlMessage.Signature = signer.sign(this.options.privateCert, 'base64'); | ||
SAML.prototype.signRequest = function (xml) { | ||
var signer = crypto.createSign('RSA-SHA1'); | ||
signer.update(xml); | ||
return signer.sign(this.options.privateCert, 'base64'); | ||
}; | ||
@@ -145,2 +94,4 @@ | ||
var instant = self.generateInstant(); | ||
var protocol = self.options.protocol || (req.protocol || 'http').concat('://'); | ||
var callbackUrl; | ||
var forceAuthn = self.options.forceAuthn || false; | ||
@@ -156,2 +107,9 @@ | ||
.then(function(){ | ||
// Post-auth destination | ||
if (self.options.callbackUrl) { | ||
callbackUrl = self.options.callbackUrl; | ||
} else { | ||
callbackUrl = protocol + req.headers.host + self.options.path; | ||
} | ||
var request = { | ||
@@ -164,3 +122,3 @@ 'samlp:AuthnRequest': { | ||
'@ProtocolBinding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', | ||
'@AssertionConsumerServiceURL': self.getCallbackUrl(req), | ||
'@AssertionConsumerServiceURL': callbackUrl, | ||
'@Destination': self.options.entryPoint, | ||
@@ -235,10 +193,2 @@ 'saml:Issuer' : { | ||
if (typeof(req.user.nameQualifier) !== 'undefined') { | ||
request['samlp:LogoutRequest']['saml:NameID']['@NameQualifier'] = req.user.nameQualifier; | ||
} | ||
if (typeof(req.user.spNameQualifier) !== 'undefined') { | ||
request['samlp:LogoutRequest']['saml:NameID']['@SPNameQualifier'] = req.user.spNameQualifier; | ||
} | ||
if (req.user.sessionIndex) { | ||
@@ -314,4 +264,4 @@ request['samlp:LogoutRequest']['saml2p:SessionIndex'] = { | ||
if (self.options.privateCert) { | ||
// sets .SigAlg and .Signature | ||
self.signRequest(samlMessage); | ||
samlMessage.SigAlg = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'; | ||
samlMessage.Signature = self.signRequest(querystring.stringify(samlMessage)); | ||
} | ||
@@ -405,3 +355,3 @@ Object.keys(samlMessage).forEach(function(k) { | ||
return false; | ||
var signature = signatures[0]; | ||
var signature = signatures[0].toString(); | ||
var sig = new xmlCrypto.SignedXml(); | ||
@@ -618,4 +568,2 @@ sig.keyInfoProvider = { | ||
profile.nameIDFormat = nameID[0].$.Format; | ||
profile.nameQualifier = nameID[0].$.NameQualifier; | ||
profile.spNameQualifier = nameID[0].$.SPNameQualifier; | ||
} | ||
@@ -699,7 +647,3 @@ } | ||
if (attributeStatement) { | ||
var attributes = [].concat.apply([], attributeStatement.filter(function (attr) { | ||
return Array.isArray(attr.Attribute); | ||
}).map(function (attr) { | ||
return attr.Attribute; | ||
})); | ||
var attributes = attributeStatement[0].Attribute; | ||
@@ -712,6 +656,2 @@ var attrValueMapper = function(value) { | ||
attributes.forEach(function (attribute) { | ||
if(!attribute.hasOwnProperty('AttributeValue')) { | ||
// if attributes has no AttributeValue child, continue | ||
return; | ||
} | ||
var value = attribute.AttributeValue; | ||
@@ -768,3 +708,2 @@ if (value.length === 1) { | ||
var xml = new Buffer(container.SAMLRequest, 'base64').toString('utf8'); | ||
var dom = new xmldom.DOMParser().parseFromString(xml); | ||
var parserConfig = { | ||
@@ -781,3 +720,3 @@ explicitRoot: true, | ||
// Check if this document has a valid top-level signature | ||
if (self.options.cert && !self.validateSignature(xml, dom.documentElement, self.options.cert)) { | ||
if (self.options.cert && !self.validateSignature(xml, self.options.cert)) { | ||
return callback(new Error('Invalid signature')); | ||
@@ -816,6 +755,2 @@ } | ||
} | ||
var sessionIndex = request.SessionIndex; | ||
if (sessionIndex) { | ||
profile.sessionIndex = sessionIndex[0]; | ||
} | ||
@@ -829,14 +764,3 @@ callback(null, profile, true); | ||
SAML.prototype.generateServiceProviderMetadata = function( decryptionCert ) { | ||
var metadata = { | ||
'EntityDescriptor' : { | ||
'@xmlns': 'urn:oasis:names:tc:SAML:2.0:metadata', | ||
'@xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#', | ||
'@entityID': this.options.issuer, | ||
'@ID': this.options.issuer.replace(/\W/g, '_'), | ||
'SPSSODescriptor' : { | ||
'@protocolSupportEnumeration': 'urn:oasis:names:tc:SAML:2.0:protocol', | ||
}, | ||
} | ||
}; | ||
var keyDescriptor = null; | ||
if (this.options.decryptionPvk) { | ||
@@ -852,3 +776,3 @@ if (!decryptionCert) { | ||
metadata.EntityDescriptor.SPSSODescriptor.KeyDescriptor = { | ||
keyDescriptor = { | ||
'ds:KeyInfo' : { | ||
@@ -870,15 +794,24 @@ 'ds:X509Data' : { | ||
if (this.options.logoutCallbackUrl) { | ||
metadata.EntityDescriptor.SPSSODescriptor.SingleLogoutService = { | ||
'@Binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', | ||
'@Location': this.options.logoutCallbackUrl | ||
}; | ||
if (!this.options.callbackUrl) { | ||
throw new Error( | ||
"Unable to generate service provider metadata when callbackUrl option is not set"); | ||
} | ||
metadata.EntityDescriptor.SPSSODescriptor.NameIDFormat = this.options.identifierFormat; | ||
metadata.EntityDescriptor.SPSSODescriptor.AssertionConsumerService = { | ||
'@index': '1', | ||
'@isDefault': 'true', | ||
'@Binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', | ||
'@Location': this.getCallbackUrl({}) | ||
var metadata = { | ||
'EntityDescriptor' : { | ||
'@xmlns': 'urn:oasis:names:tc:SAML:2.0:metadata', | ||
'@xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#', | ||
'@entityID': this.options.issuer, | ||
'SPSSODescriptor' : { | ||
'@protocolSupportEnumeration': 'urn:oasis:names:tc:SAML:2.0:protocol', | ||
'KeyDescriptor' : keyDescriptor, | ||
'NameIDFormat' : this.options.identifierFormat, | ||
'AssertionConsumerService' : { | ||
'@index': '1', | ||
'@isDefault': 'true', | ||
'@Binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', | ||
'@Location': this.options.callbackUrl | ||
} | ||
}, | ||
} | ||
}; | ||
@@ -885,0 +818,0 @@ |
{ | ||
"name": "passport-saml-restify", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"licenses": [ | ||
@@ -34,11 +34,10 @@ { | ||
"main": "./lib/passport-saml-restify", | ||
"license": "SEE LICENSE IN LICENSE", | ||
"dependencies": { | ||
"passport-restify": "1.0.1", | ||
"passport-restify": "1.0.0", | ||
"q": "1.1.x", | ||
"xml-crypto": "0.8.4", | ||
"xml-encryption": "~0.7", | ||
"xml2js": "0.4.x", | ||
"xml-crypto": "0.8.x", | ||
"xmldom": "0.1.x", | ||
"xmlbuilder": "2.5.x", | ||
"xml-encryption": "~0.7" | ||
"xmldom": "0.1.x" | ||
}, | ||
@@ -51,6 +50,5 @@ "devDependencies": { | ||
"request": "*", | ||
"restify": "4.0.3", | ||
"restify": "restify/node-restify", | ||
"should": "*", | ||
"sinon": "^1.10.2", | ||
"passport": "0.3.x" | ||
"sinon": "^1.10.2" | ||
}, | ||
@@ -57,0 +55,0 @@ "engines": { |
@@ -48,3 +48,2 @@ Passport-SAML | ||
* `protocol`: protocol for callback; will be combined with path and server host information to construct callback url if `callbackUrl` is not specified (default: `http://`) | ||
* `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 | ||
@@ -55,3 +54,2 @@ * `issuer`: issuer string to supply to identity provider | ||
* `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' | ||
* Additional SAML behaviors | ||
@@ -66,3 +64,2 @@ * `additionalParams`: dictionary of additional query params to add to all requests | ||
* `forceAuthn`: if set to true, the initial SAML request from the service provider specifies that the IdP should force re-authentication of the user, even if they possess a valid session. | ||
* `skipRequestCompression`: if set to true, the SAML request from the service provider won't be compressed. | ||
* InResponseTo Validation | ||
@@ -77,3 +74,2 @@ * `validateInResponseTo`: if truthy, then InResponseTo will be validated from incoming SAML responses | ||
* `additionalLogoutParams`: dictionary of additional query params to add to 'logout' requests | ||
* `logoutCallbackUrl`: The value with which to populate the `Location` attribute in the `SingleLogoutService` elements in the generated service provider metadata. | ||
@@ -146,4 +142,2 @@ ### Provide the authentication callback | ||
For more detailed instructions, see [this document from Tim Brody](docs/adfs/README.md). | ||
## SAML Response Validation - NotBefore and NotOnOrAfter | ||
@@ -150,0 +144,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Misc. License Issues
License(Experimental) A package's licensing information has fine-grained problems.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
8
0
31
231824
17
2349
204
+ Addedpassport-restify@1.0.0(transitive)
+ Addedxml-crypto@0.8.4(transitive)
- Removedpassport-restify@1.0.1(transitive)
- Removedxml-crypto@0.8.5(transitive)
Updatedpassport-restify@1.0.0
Updatedxml-crypto@0.8.4