forked from node-saml/passport-saml
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue node-saml#206: Support signing AuthnRequests using the HTTP-POS…
…T Binding This commit adds support for signing AuthnRequests in the SAML HTTP-POST binding. In the POST Binding the signature sits inside the SAML message (as opposed to the Redirect binding, where the signture lives in the URL's query string). This will help suppport identity providers that require signed AuthnRequests over the HTTP-POST binding. Two new configuration options have been added: * `digestAlgorithm`: allows you to specify the digest algorithm for the signature. * `xmlSignatureTransforms`: allows you to configure which XML transforms to use.
- Loading branch information
1 parent
6d1215b
commit 571214e
Showing
7 changed files
with
120 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
node_modules/ | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
var crypto = require('crypto'); | ||
|
||
exports.getSigningAlgorithm = function getSigningAlgorithm (shortName) { | ||
switch(shortName) { | ||
case 'sha256': | ||
return 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; | ||
case 'sha512': | ||
return 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'; | ||
default: | ||
return 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'; | ||
} | ||
}; | ||
|
||
exports.getDigestAlgorithm = function getDigestAlgorithm (shortName) { | ||
switch(shortName) { | ||
case 'sha256': | ||
return 'http://www.w3.org/2001/04/xmlenc#sha256'; | ||
case 'sha512': | ||
return 'http://www.w3.org/2001/04/xmlenc#sha512'; | ||
default: | ||
return 'http://www.w3.org/2000/09/xmldsig#sha1'; | ||
} | ||
}; | ||
|
||
exports.getSigner = function getSigner (shortName) { | ||
switch(shortName) { | ||
case 'sha256': | ||
return crypto.createSign('RSA-SHA256'); | ||
case 'sha512': | ||
return crypto.createSign('RSA-SHA512'); | ||
default: | ||
return crypto.createSign('RSA-SHA1'); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
var SignedXml = require('xml-crypto').SignedXml; | ||
var algorithms = require('./algorithms'); | ||
|
||
var authnRequestXPath = '/*[local-name(.)="AuthnRequest" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:protocol"]'; | ||
var defaultTransforms = [ 'http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#' ]; | ||
|
||
function signSamlPost(samlMessage, xpath, options) { | ||
if (!samlMessage) throw new Error('samlMessage is required'); | ||
if (!xpath) throw new Error('xpath is required'); | ||
if (!options || !options.privateCert) throw new Error('options.privateCert is required'); | ||
|
||
var transforms = options.xmlSignatureTransforms || defaultTransforms; | ||
var sig = new SignedXml(); | ||
if (options.signatureAlgorithm) { | ||
sig.signatureAlgorithm = algorithms.getSigningAlgorithm(options.signatureAlgorithm); | ||
} | ||
sig.addReference(xpath, transforms, algorithms.getDigestAlgorithm(options.digestAlgorithm)); | ||
sig.signingKey = options.privateCert; | ||
sig.computeSignature(samlMessage); | ||
return sig.getSignedXml(); | ||
} | ||
|
||
function signAuthnRequestPost(authnRequest, options) { | ||
return signSamlPost(authnRequest, authnRequestXPath, options); | ||
} | ||
|
||
exports.signSamlPost = signSamlPost; | ||
exports.signAuthnRequestPost = signAuthnRequestPost; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
const fs = require('fs'); | ||
const should = require('should'); | ||
const samlPostSigning = require('../lib/passport-saml/saml-post-signing'); | ||
const signSamlPost = samlPostSigning.signSamlPost; | ||
const signAuthnRequestPost = samlPostSigning.signAuthnRequestPost; | ||
|
||
const signingKey = fs.readFileSync(__dirname + '/static/key.pem'); | ||
|
||
describe('SAML POST Signing', function () { | ||
it('should sign a simple saml request', function () { | ||
var xml = '<SAMLRequest/>'; | ||
var result = signSamlPost(xml, '/SAMLRequest', { privateCert: signingKey }); | ||
result.should.match(/<DigestValue>[A-Za-z0-9\/\+\=]+<\/DigestValue>/); | ||
result.should.match(/<SignatureValue>[A-Za-z0-9\/\+\=]+<\/SignatureValue>/); | ||
}); | ||
|
||
it('should sign and digest with SHA256 when specified', function () { | ||
var xml = '<SAMLRequest/>'; | ||
var options = { | ||
signatureAlgorithm: 'sha256', | ||
digestAlgorithm: 'sha256', | ||
privateCert: signingKey | ||
} | ||
var result = signSamlPost(xml, '/SAMLRequest', options); | ||
result.should.match(/<SignatureMethod Algorithm="http:\/\/www.w3.org\/2001\/04\/xmldsig-more#rsa-sha256"/); | ||
result.should.match(/<Transform Algorithm="http:\/\/www.w3.org\/2001\/10\/xml-exc-c14n#"\/>/); | ||
result.should.match(/<Transform Algorithm="http:\/\/www.w3.org\/2000\/09\/xmldsig#enveloped-signature"\/>/); | ||
result.should.match(/<DigestMethod Algorithm="http:\/\/www.w3.org\/2001\/04\/xmlenc#sha256"\/>/); | ||
}); | ||
|
||
it('should sign an AuthnRequest', function () { | ||
var xml = '<AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:protocol" />'; | ||
var result = signAuthnRequestPost(xml, { privateCert: signingKey }); | ||
result.should.match(/<DigestValue>[A-Za-z0-9\/\+\=]+<\/DigestValue>/); | ||
result.should.match(/<SignatureValue>[A-Za-z0-9\/\+\=]+<\/SignatureValue>/); | ||
}); | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.