With HTTP Redirect binding the signature has to be outside of XML

This commit is contained in:
Henri Bergius
2012-07-05 13:18:08 +02:00
parent d317547de9
commit 825619f4bc
+24 -14
View File
@@ -1,6 +1,7 @@
var zlib = require('zlib');
var xml2js = require('xml2js');
var crypto = require('xml-crypto');
var xmlCrypto = require('xml-crypto');
var crypto = require('crypto');
var xmldom = require('xmldom');
var SAML = function (options) {
@@ -46,11 +47,9 @@ SAML.prototype.generateInstant = function () {
};
SAML.prototype.signRequest = function (xml) {
var sig = new crypto.SignedXml();
sig.addReference("/*[local-name(.)='AuthnRequest' and namespace-uri(.)='urn:oasis:names:tc:SAML:2.0:protocol']");
sig.signingKey = this.options.privateCert;
sig.computeSignature(xml);
return sig.getSignedXml();
var signer = crypto.createSign('RSA-SHA1');
signer.update(xml);
return signer.sign(this.options.privateCert, 'base64');
}
SAML.prototype.generateRequest = function (req) {
@@ -58,7 +57,11 @@ SAML.prototype.generateRequest = function (req) {
var instant = this.generateInstant();
// Post-auth destination
var callbackUrl = this.options.protocol + req.headers.host + this.options.path;
if (this.options.callbackUrl) {
callbackUrl = this.options.callbackUrl;
} else {
var callbackUrl = this.options.protocol + req.headers.host + this.options.path;
}
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 + "\">" +
@@ -68,10 +71,6 @@ SAML.prototype.generateRequest = function (req) {
"<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:AuthnRequest>";
if (this.options.privateCert) {
request = this.signRequest(request);
}
return request;
};
@@ -86,7 +85,18 @@ SAML.prototype.getAuthorizeUrl = function (req, callback) {
var base64 = buffer.toString('base64');
var encoded = encodeURIComponent(base64);
callback(null, self.options.entryPoint + '?SAMLRequest=' + encoded);
var target = self.options.entryPoint + '?'
var samlRequest = 'SAMLRequest=' + encoded;
if (self.options.privateCert) {
var signature = self.signRequest(request);
samlRequest += '&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1';
var signature = self.signRequest(samlRequest);
samlRequest += '&Signature=' + signature;
}
target += samlRequest;
callback(null, target);
});
};
@@ -100,8 +110,8 @@ SAML.prototype.certToPEM = function (cert) {
SAML.prototype.validateSignature = function (xml, cert) {
var self = this;
var doc = new xmldom.DOMParser().parseFromString(xml);
var signature = crypto.xpath.SelectNodes(doc, "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0];
var sig = new crypto.SignedXml();
var signature = xmlCrypto.xpath.SelectNodes(doc, "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0];
var sig = new xmlCrypto.SignedXml();
sig.keyInfoProvider = {
getKeyInfo: function (key) {
return "<X509Data></X509Data>"