diff --git a/src/saml.ts b/src/saml.ts index f821216..d2fbb5a 100644 --- a/src/saml.ts +++ b/src/saml.ts @@ -1,5 +1,7 @@ import { SAML, SamlConfig } from '@node-saml/node-saml'; -import { signAuthnRequestPost } from '@node-saml/node-saml/lib/saml-post-signing'; +// import { signAuthnRequestPost } from '@node-saml/node-saml/lib/saml-post-signing'; +import { signAuthRequest } from './signAuthRequest'; + import { SpidRequest } from './request'; import { SamlSpidProfile, SpidConfig } from './types'; import { SpidResponse } from './response'; @@ -31,7 +33,18 @@ export class SpidSAML extends SAML { xml = req.generate(this.options).xml(); if (this.options.authnRequestBinding === 'HTTP-POST') { // re-sign request - xml = signAuthnRequestPost(xml, this.options as any); + //xml = signAuthnRequestPost(xml, this.options as any); + + const { spid, saml } = this.spidConfig; + const { privateKey, signatureAlgorithm } = saml; + const cert = spid.serviceProvider.certificate; + xml = signAuthRequest(xml, { + signatureAlgorithm: signatureAlgorithm, + privateKey, + certificate: cert, + action: 'after', + nodeName: 'AuthnRequest', + }); } const { cache } = this.spidConfig; const cacheData: CacheData = { diff --git a/src/signAuthRequest.ts b/src/signAuthRequest.ts new file mode 100644 index 0000000..e7ef8e5 --- /dev/null +++ b/src/signAuthRequest.ts @@ -0,0 +1,42 @@ +import { SignedXml } from 'xml-crypto'; + +const authnRequestXPath = + '/*[local-name(.)="AuthnRequest" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:protocol"]'; +const issuerXPath = + '/*[local-name(.)="Issuer" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:assertion"]'; + +export const signAuthRequest = ( + xml: string, + options: { + privateKey: string | Buffer; + signatureAlgorithm: string; + nodeName: string; + certificate?: string; + action?: 'prepend' | 'append' | 'after'; + }, +) => { + const { privateKey, signatureAlgorithm, nodeName, certificate, action } = + options; + const sig = new SignedXml(); + sig.signingKey = privateKey; + if (certificate) + sig.keyInfoProvider = { + file: '', + getKey: () => Buffer.from(privateKey), + getKeyInfo: () => + `${certificate}`, + }; + sig.signatureAlgorithm = `http://www.w3.org/2001/04/xmldsig-more#rsa-${signatureAlgorithm}`; + sig.addReference( + `//*[local-name(.)='${nodeName}']`, + [ + 'http://www.w3.org/2000/09/xmldsig#enveloped-signature', + 'http://www.w3.org/2001/10/xml-exc-c14n#', + ], + `http://www.w3.org/2001/04/xmlenc#${signatureAlgorithm}`, + ); + sig.computeSignature(xml, { + location: { reference: authnRequestXPath + issuerXPath, action: 'after' }, + }); + return sig.getSignedXml(); +};