Skip to content

Commit

Permalink
Add support for service provider transformation algorithms in asserti…
Browse files Browse the repository at this point in the history
…on signature creation (#253)
  • Loading branch information
morgan-monger authored and tngan committed Mar 24, 2019
1 parent 32948df commit 7d1b6f0
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
10 changes: 10 additions & 0 deletions docs/signed-saml-response.md
Expand Up @@ -39,6 +39,16 @@ There are different examples of signing scheme supported in samlify.
To guarantee the setting in between idp-sp pair is synchronized, determination of assertion signature depends on the sp setting. Set `WantAssertionsSigned` to true in corresponding sp's metadata or `wantAssertionsSigned` in constructor if metadata is not set.

```javascript
const sp = ServiceProvider({
// ...
metadata: readFileSync('./sp-metadata.xml'),
// must have if assertion signature fails validation
// transformationAlgorithms: [
// 'http://www.w3.org/2000/09/xmldsig#enveloped-signature',
// 'http://www.w3.org/2001/10/xml-exc-c14n#',
// ],
});

const idp = IdentityProvider({
// ...
metadata: readFileSync('./idp-metatadata.xml'),
Expand Down
1 change: 1 addition & 0 deletions src/binding-post.ts
Expand Up @@ -140,6 +140,7 @@ async function base64LoginResponse(requestInfo: any = {}, entity: any, user: any
rawSamlResponse = libsaml.constructSAMLSignature({
...config,
rawSamlMessage: rawSamlResponse,
transformationAlgorithms: spSetting.transformationAlgorithms,
referenceTagXPath: "/*[local-name(.)='Response']/*[local-name(.)='Assertion']",
signatureConfig: {
prefix: 'ds',
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Expand Up @@ -82,6 +82,7 @@ export interface ServiceProviderSettings {
logoutRequestTemplate?: SAMLDocumentTemplate;
signingCert?: string | Buffer;
encryptCert?: string | Buffer;
transformationAlgorithms?: string[];
}

export interface IdentityProviderSettings {
Expand Down
28 changes: 28 additions & 0 deletions test/flow.ts
Expand Up @@ -265,6 +265,34 @@ test('send response with signed assertion and parse it', async t => {
t.is(extract.response.inResponseTo, 'request_id');
});

test('send response with signed assertion + custom transformation algorithms and parse it', async t => {
// sender (caution: only use metadata and public key when declare pair-up in oppoent entity)
const signedAssertionSp = serviceProvider(
{
...defaultSpConfig,
transformationAlgorithms: [
'http://www.w3.org/2000/09/xmldsig#enveloped-signature',
'http://www.w3.org/2001/10/xml-exc-c14n#'
]
}
);

const user = { email: 'user@esaml2.com' };
const { id, context: SAMLResponse } = await idpNoEncrypt.createLoginResponse(signedAssertionSp, sampleRequestInfo, 'post', user, createTemplateCallback(idpNoEncrypt, sp, user));
// receiver (caution: only use metadata and public key when declare pair-up in oppoent entity)
const { samlContent, extract } = await sp.parseLoginResponse(idpNoEncrypt, 'post', { body: { SAMLResponse } });
t.is(typeof id, 'string');
t.is(samlContent.startsWith('<samlp:Response'), true);
t.is(samlContent.endsWith('/samlp:Response>'), true);
t.is(extract.nameID, 'user@esaml2.com');
t.is(extract.response.inResponseTo, 'request_id');

// Verify xmldsig#enveloped-signature is included in the response
if (samlContent.indexOf('http://www.w3.org/2000/09/xmldsig#enveloped-signature') === -1) {
t.fail();
}
});

test('send response with [custom template] signed assertion and parse it', async t => {
// sender (caution: only use metadata and public key when declare pair-up in oppoent entity)
const requestInfo = { extract: { request: { id: 'request_id' } } };
Expand Down

0 comments on commit 7d1b6f0

Please sign in to comment.