Skip to content

Commit 7378e60

Browse files
sultanhqrassul-findmypastJAParsonsjondarrermattkrick
committed
fix: TypeError when parsing login response tngan#399
fix: throw when cert is null tngan#397 Co-authored-by: rassul-findmypast <[email protected]> Co-authored-by: JAParsons <[email protected]> Co-authored-by: Jonathan Darrer <[email protected]> Co-authored-by: Matt Krick <[email protected]>
1 parent d9ba89d commit 7378e60

File tree

7 files changed

+262
-4
lines changed

7 files changed

+262
-4
lines changed

src/extractor.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ export function extract(context: string, fields) {
209209
const shortcut = field.shortcut;
210210
// get optional fields
211211
const index = field.index;
212+
const excludeAttribute = field.excludeAttribute;
212213
const attributePath = field.attributePath;
213214

214215
// set allowing overriding if there is a shortcut injected
@@ -361,6 +362,30 @@ export function extract(context: string, fields) {
361362
[key]: attributeValues[0]
362363
};
363364
}
365+
366+
// case: single excluded attribute
367+
/*
368+
{
369+
key: 'sharedCertificate',
370+
excludeAttribute: 'use',
371+
localPath: ['EntityDescriptor', '~SSODescriptor', 'KeyDescriptor'],
372+
attributePath: ['KeyInfo', 'X509Data', 'X509Certificate'],
373+
attributes: [],
374+
}
375+
*/
376+
if (excludeAttribute) {
377+
const fullPath = `${baseXPath}[not(@${excludeAttribute})]${buildAbsoluteXPath(attributePath)}`;
378+
const node = select(fullPath, targetDoc);
379+
return {
380+
...result,
381+
[key]: node.length > 0
382+
? node
383+
.filter((n: Node) => n.firstChild)
384+
.map((n: Node) => n.firstChild!.nodeValue)
385+
: undefined
386+
};
387+
}
388+
364389
// case: zero attribute
365390
/*
366391
{

src/libsaml.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ const libSaml = () => {
412412
const certificateNode = select(".//*[local-name(.)='X509Certificate']", signatureNode) as any;
413413
// certificate in metadata
414414
let metadataCert: any = opts.metadata.getX509Certificate(certUse.signing);
415+
if (!metadataCert) {
416+
throw new Error('INVALID_CERTIFICATE_PROVIDED')
417+
}
415418
// flattens the nested array of Certificates from each KeyDescriptor
416419
if (Array.isArray(metadataCert)) {
417420
metadataCert = flattenDeep(metadataCert);

src/metadata.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ export default class Metadata implements MetadataInterface {
4545
{
4646
// shared certificate for both encryption and signing
4747
key: 'sharedCertificate',
48-
localPath: ['EntityDescriptor', '~SSODescriptor', 'KeyDescriptor', 'KeyInfo', 'X509Data', 'X509Certificate'],
48+
excludeAttribute: 'use',
49+
localPath: ['EntityDescriptor', '~SSODescriptor', 'KeyDescriptor'],
50+
attributePath: ['KeyInfo', 'X509Data', 'X509Certificate'],
4951
attributes: []
5052
},
5153
{
@@ -72,8 +74,14 @@ export default class Metadata implements MetadataInterface {
7274
const sharedCertificate = this.meta.sharedCertificate;
7375
if (typeof sharedCertificate === 'string') {
7476
this.meta.certificate = {
75-
signing: sharedCertificate,
76-
encryption: sharedCertificate
77+
signing: this.meta.certificate.signing || sharedCertificate,
78+
encryption: this.meta.certificate.encryption || sharedCertificate
79+
};
80+
delete this.meta.sharedCertificate;
81+
} else if (Array.isArray(sharedCertificate)) {
82+
this.meta.certificate = {
83+
signing: this.meta.certificate.signing || sharedCertificate[0],
84+
encryption: this.meta.certificate.encryption || sharedCertificate[0]
7785
};
7886
delete this.meta.sharedCertificate;
7987
}

test/index.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,13 @@ test('getAssertionConsumerService with two bindings', t => {
243243
t.is(libsaml.verifySignature(responseSignedByCert2, { metadata: idpRollingCert.entityMeta, signatureAlgorithm: signatureAlgorithms.RSA_SHA256 })[0], true);
244244

245245
});
246-
246+
test('verify a XML signature with metadata but with multiple anonymous certificates, where some of them are incorrect', t => {
247+
const responseSignedByCert1 = String(readFileSync('./test/misc/response_signed_cert1.xml'));
248+
const metadata = idpMetadata(
249+
readFileSync("./test/misc/idpmeta_multiple_anonymous_certs.xml")
250+
);
251+
t.is(libsaml.verifySignature(responseSignedByCert1, { metadata: metadata, signatureAlgorithm: signatureAlgorithms.RSA_SHA256 })[0], true);
252+
});
247253
test('verify a XML signature signed by RSA-SHA1 with .cer keyFile', t => {
248254
const xml = String(readFileSync('./test/misc/signed_request_sha1.xml'));
249255
t.is(libsaml.verifySignature(xml, { keyFile: './test/key/sp/cert.cer' })[0], true);
@@ -441,3 +447,23 @@ test('contains explicit certificate declaration for signing and encryption in me
441447
t.not(encryptionCertificate, null);
442448
t.not(signingCertificate, encryptionCertificate);
443449
});
450+
451+
test('returns different certificates for signing and encryption when metadata contains one signing and one anonymous certificate', t => {
452+
const metadata = idpMetadata(
453+
readFileSync("./test/misc/idpmeta_one_signing_and_one_anonymous_cert.xml")
454+
);
455+
const signingCertificate = metadata.getX509Certificate("signing");
456+
const encryptionCertificate = metadata.getX509Certificate("encryption");
457+
t.not(signingCertificate, encryptionCertificate);
458+
});
459+
460+
test('returns the same certificate for signing and encryption when multiple anonymous certificates are present', t => {
461+
const metadata = idpMetadata(
462+
readFileSync("./test/misc/idpmeta_multiple_anonymous_certs.xml")
463+
);
464+
const signingCertificate = metadata.getX509Certificate("signing");
465+
const encryptionCertificate = metadata.getX509Certificate("encryption");
466+
t.not(signingCertificate, null);
467+
t.not(encryptionCertificate, null);
468+
t.is(signingCertificate, encryptionCertificate);
469+
});

test/libsaml.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import test from "ava";
2+
import { SignedXml } from "xml-crypto";
3+
import libSaml from "../src/libsaml";
4+
5+
const fakeMetadataInvalid = {
6+
getX509Certificate: (_usage: string) => null,
7+
};
8+
9+
const fakeMetadataValid = {
10+
getX509Certificate: (_usage: string) => "VALIDCERT",
11+
};
12+
13+
test("throws ERR_UNDEFINED_SIGNATURE_VERIFIER_OPTIONS when neither keyFile nor metadata provided", (t) => {
14+
const xml = "<Response><Signature></Signature></Response>";
15+
const error = t.throws(() => {
16+
libSaml.verifySignature(xml, { signatureAlgorithm: "dummy" } as any);
17+
});
18+
t.is(error!.message, "ERR_UNDEFINED_SIGNATURE_VERIFIER_OPTIONS");
19+
});
20+
21+
test("throws ERR_ZERO_SIGNATURE when no signature element exists", (t) => {
22+
const xml = "<Response></Response>";
23+
const error = t.throws(() => {
24+
libSaml.verifySignature(xml, {
25+
keyFile: "dummy.pem",
26+
signatureAlgorithm: "dummy",
27+
} as any);
28+
});
29+
t.is(error!.message, "ERR_ZERO_SIGNATURE");
30+
});
31+
32+
test("throws ERR_POTENTIAL_WRAPPING_ATTACK when wrapping element is present", (t) => {
33+
// Construct XML with a wrapping assertion inside SubjectConfirmationData
34+
const xml = `
35+
<Response>
36+
<Signature>
37+
<X509Data>
38+
<X509Certificate>VALIDCERT</X509Certificate>
39+
</X509Data>
40+
</Signature>
41+
<Assertion ID="ID">
42+
<Subject>
43+
<SubjectConfirmation>
44+
<SubjectConfirmationData>
45+
<Assertion></Assertion>
46+
</SubjectConfirmationData>
47+
</SubjectConfirmation>
48+
</Subject>
49+
</Assertion>
50+
</Response>
51+
`;
52+
const error = t.throws(() => {
53+
libSaml.verifySignature(xml, {
54+
keyFile: "dummy.pem",
55+
signatureAlgorithm: "dummy",
56+
} as any);
57+
});
58+
t.is(error!.message, "ERR_POTENTIAL_WRAPPING_ATTACK");
59+
});
60+
61+
test("throws INVALID_CERTIFICATE_PROVIDED when metadata returns no certificate", (t) => {
62+
// Signature element is present and metadata returns null certificate.
63+
const xml = `
64+
<Response>
65+
<Signature>
66+
<X509Data>
67+
<X509Certificate>ANOTHERCERT</X509Certificate>
68+
</X509Data>
69+
</Signature>
70+
<Assertion ID="ID">Content</Assertion>
71+
</Response>
72+
`;
73+
const error = t.throws(() => {
74+
libSaml.verifySignature(xml, {
75+
metadata: fakeMetadataInvalid,
76+
signatureAlgorithm: "dummy",
77+
} as any);
78+
});
79+
t.is(error!.message, "INVALID_CERTIFICATE_PROVIDED");
80+
});
81+
82+
test("returns valid verification result when signature is valid", (t) => {
83+
// Override SignedXml methods to simulate valid signature checking
84+
const origCheckSignature = SignedXml.prototype.checkSignature;
85+
const origLoadSignature = SignedXml.prototype.loadSignature;
86+
SignedXml.prototype.checkSignature = () => true;
87+
SignedXml.prototype.loadSignature = () => {};
88+
89+
// Create a minimal XML with a Signature element containing a valid certificate node
90+
const xml = `
91+
<Response>
92+
<Signature>
93+
<X509Data>
94+
<X509Certificate>VALIDCERT</X509Certificate>
95+
</X509Data>
96+
</Signature>
97+
<Assertion ID="ID">AssertionContent</Assertion>
98+
</Response>
99+
`;
100+
const result = libSaml.verifySignature(xml, {
101+
metadata: fakeMetadataValid,
102+
signatureAlgorithm: "dummy",
103+
} as any);
104+
t.true(Array.isArray(result));
105+
t.true(result[0] === true);
106+
t.regex(typeof result[1] === "string" ? result[1] : "", /Assertion/);
107+
108+
// Restore the original methods
109+
SignedXml.prototype.checkSignature = origCheckSignature;
110+
SignedXml.prototype.loadSignature = origLoadSignature;
111+
});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<EntityDescriptor ID="SMa4fd5378c57fa016d03c6b27a8e0cf6f99ed2073b" entityID="https://idp.example.com/metadata"
2+
xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
3+
<IDPSSODescriptor WantAuthnRequestsSigned="true" ID="SM14a93e72cb19411b4fc4eec882c98b12dbf55cea68e" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
4+
<KeyDescriptor>
5+
<KeyInfo ID="SM4cee9750ee17bb2f60ddbe556a2798218f7a5bbed"
6+
xmlns:ns1="http://www.w3.org/2000/09/xmldsig#">
7+
<X509Data>
8+
<X509Certificate>MIIDlzCCAn+gAwIBAgIJAO1ymQc33+bWMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAkhLMRMwEQYDVQQIDApTb21lLVN0YXRlMRowGAYDVQQKDBFJZGVudGl0eSBQcm92aWRlcjEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxDDAKBgNVBAMMA0lEUDAeFw0xNTA3MDUxODAyMjdaFw0xODA3MDQxODAyMjdaMGIxCzAJBgNVBAYTAkhLMRMwEQYDVQQIDApTb21lLVN0YXRlMRowGAYDVQQKDBFJZGVudGl0eSBQcm92aWRlcjEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxDDAKBgNVBAMMA0lEUDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAODZsWhCe+yG0PalQPTUoD7yko5MTWMCRxJ8hSm2k7mG3Eg/Y2v0EBdCmTw7iDCevRqUmbmFnq7MROyV4eriJzh0KabAdZf7/k6koghst3ZUtWOwzshyxkBtWDwGmBpQGTGsKxJ8M1js3aSqNRXBT4OBWM9w2Glt1+8ty30RhYv3pSF+/HHLH7Ac+vLSIAlokaFW34RWTcJ/8rADuRWlXih4GfnIu0W/ncm5nTSaJiRAvr3dGDRO/khiXoJdbbOj7dHPULxVGbH9IbPK76TCwLbF7ikIMsPovVbTrpyL6vsbVUKeEl/5GKppTwp9DLAOeoSYpCYkkDkYKu9TRQjF02MCAwEAAaNQME4wHQYDVR0OBBYEFP2ut2AQdy6D1dwdwK740IHmbh38MB8GA1UdIwQYMBaAFP2ut2AQdy6D1dwdwK740IHmbh38MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBANMZUoPNmHzgja2PYkbvBYMHmpvUkVoiuvQ9cJPlqGTB2CRfG68BNNs/Clz8P7cIrAdkhCUwi1rSBhDuslGFNrSaIpv6B10FpBuKwef3G7YrPWFNEN6khY7aHNWSTHqKgs1DrGef2B9hvkrnHWbQVSVXrBFKe1wTCqcgGcOpYoSK7L8C6iX6uIA/uZYnVQ4NgBrizJ0azkjdegz3hwO/gt4malEURy8D85/AAVt6PAzhpb9VJUGxSXr/EfntVUEz3L2gUFWWk1CnZFyz0rIOEt/zPmeAY8BLyd/Tjxm4Y+gwNazKq5y9AJS+m858b/nM4QdCnUE4yyoWAJDUHiAmvFA=</X509Certificate>
9+
</X509Data>
10+
</KeyInfo>
11+
</KeyDescriptor>
12+
<KeyDescriptor>
13+
<KeyInfo ID="SM4cee9750ee17cc2f60ddbe777a2798218f7a5bbef"
14+
xmlns:ns1="http://www.w3.org/2000/09/xmldsig#">
15+
<X509Data>
16+
<X509Certificate>MIIFLjCCAxYCCQCqGHhTssya9jANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJISzESMBAGA1UECAwJSG9uZyBLb25nMRIwEAYDVQQHDAlIb25nIEtvbmcxEDAOBgNVBAoMB3NhbWxpZnkxEDAOBgNVBAMMB3NhbWxpZnkwHhcNMjAwNTEwMTUyNjIzWhcNMzAwNTA4MTUyNjIzWjBZMQswCQYDVQQGEwJISzESMBAGA1UECAwJSG9uZyBLb25nMRIwEAYDVQQHDAlIb25nIEtvbmcxEDAOBgNVBAoMB3NhbWxpZnkxEDAOBgNVBAMMB3NhbWxpZnkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDQG+abAeeWjwsOZt5SkcNcw/XSJcjSyJykEbEU2iguErRuOIyBfgj0p1UVBv33uL2igeYJT3OSXmSjvMO8KvqtYN2tJAjoFjghGr8NbIEZjYS4ukMZUbwxd2bRycD9OMI9g44AUB1sfQ0UyFwzEOseW3lcW1FnhcizA8TgI0GN4NpdVruNlpgoWdP3w+Syhtq0rWebY8g/HGFruEKn8VwbUblOZdP7jNVXsd1aUMScpuMa0khzzXPDN+Q0rwl79fO4ychSeKAAERdPXA1UfDfbh9W7pcYBP0ABXd91Bf9akplmbbVOIsNbuRIcVS7WvLwCr613JuJ+EtGDcUkrSpbuRvDW85DQRHBGuoKlcSG+imHQtHqRwMwMc8P54hIEBvaFW0RfwPfzdFNe8wARtmvIeX84iwq5Yey15Ly1rdopi7t2g7qyF7C/B9gZ3tJ/gPKp2NrdCGFBcahl93Lj56WWmI0jNHn7+7Y3x6isJ3KTRXIliSrAwiK7/7UezOlWzs1k8mGQWZTD3AGGKu1cBVwuC+rh4wkLsDeHfzxavbXxVEok9p/1P28M4GiHfS0POE3Hl4RT3Q6AiYWnmFYyZ+smY97SgPwB4tTNYFjC6+9d/BllNoQb8wsPjqp6ZDn1OeY668hp+ZAcE13AFdiTBMVrcdEECCPLxg1kFk5wZdHrGwIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCyA/14hKTqfdeOVl+MQ2SLPWi7pC/t/Zv4kc361xP26FAVSSrxgXq9kVLZeJIAqCwjGHkl/DTUlA8hfLfuZx5z+NI/qIodsXAjCzsCe7paEbjvR6OQjYkR0UY4u/AOO7x2op2KDFKNuWT9KZNm8bh1mxwNKep1fJP2O5M0nMYAGYbPsLAOn7mzZyufQl8hsJwIV2s8sbft7s8vmEYZbuueQDOJCMTt+eC08LONrovYChyYmj3i5RIk8kcaodeSDo811F1B1gDvO/dmVxgrHEgoai7X6LUoiAiLkigP7udNEZxbXsRlOhBRv9w+rRXFurVFlUPkQ9UF+QB0BoyIcUxo+fZ8vCA4xEVBenVBadpFbwum6+XeTkvDoRc4sSCpm8v2qtprc8aU/0F82EzxSybYvstc5lDv7wuwCwNwfoAQ+/16kTpJvoYbOXUPv5yCA3mIuqYeA1woaWPXsE4jNOzTqv1qOZQTvXProEgK5B0FR5ILc4mfNrD2p9VGbiYf2GjCfeEzDFg174dvSn2MMp1yK5pvZEp7yFE8z1eduYN6W/7qdtss9BGpnyS5X7LuYfDvd1dHP6/JuqJDbfSVG9prYWcaMRd3FzSC7jBeetJgMyj4dunfqw8R16aONhwvICtzdFa93hYrDvTyo3ae80KFi0WGgApKeoqO5t3l1PAcaA==</X509Certificate>
17+
</X509Data>
18+
</KeyInfo>
19+
</KeyDescriptor>
20+
<KeyDescriptor>
21+
<KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
22+
<X509Data>
23+
<X509Certificate>MIID6TCCAtGgAwIBAgIJAPQQPsolUypeMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxFTATBgNVBAoTDGV4cHJlc3Mtc2FtbDEMMAoGA1UECxMDZGV2MQ4wDAYDVQQDEwVlc2FtbDAeFw0xNTEwMDMwMzU3MzRaFw0xODEwMDIwMzU3MzRaMFYxCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxFTATBgNVBAoTDGV4cHJlc3Mtc2FtbDEMMAoGA1UECxMDZGV2MQ4wDAYDVQQDEwVlc2FtbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL7dF1gUNu8en0fHMSbzf192uB8m2CTeHeEeYrmq5rau6t1WzaHwbSStd9tJ/11Arm8f8zfefFqEBA0EYbp/DMqHb9ZiLGgIff08679NOYeK/d9EAs5DzvTMTR6QqG7a4vH3jKOksIbjM35h5RVitVDxo+xWDKyvOpuNE64bJlWHOEiNxvwmcHfJ2hAd1EozaRLcJOojFHg51alUqiNIZ+vpkMAM8s3lUlcYETKqTpcnsE7c1QX60cCrFN4m3SNS98HGBEdotch8+2Myzz957cBiwg9CR05PtEfjH0gGXJbL56JmpPyY+TkEiNMtMqJ7RNkK92gZfoY2i3RdjLKOHDUCAwEAAaOBuTCBtjAdBgNVHQ4EFgQUm4zK2qBtDMICekupt3LnRBdbP9UwgYYGA1UdIwR/MH2AFJuMytqgbQzCAnpLqbdy50QXWz/VoVqkWDBWMQswCQYDVQQGEwJISzESMBAGA1UECBMJSG9uZyBLb25nMRUwEwYDVQQKEwxleHByZXNzLXNhbWwxDDAKBgNVBAsTA2RldjEOMAwGA1UEAxMFZXNhbWyCCQD0ED7KJVMqXjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA9t7VMtX93yIYIGFC20GCsMYZeZpTedxpxpjqom2dOuOUaDQgrZcGF3FVbFqTEpPtOnsKXYaCg7FJvUjxv7FIuix5H7JO6DALoJ792pfG2wwS2PvDiGFxMfGnNvb3aLnB/s6wTyWBpDYRdwlB5nj37KPk6kpFJj3N9x5BD1oTdmQqeVuacjoiemIulkc33P28tGl6Datth4WpE0LwmrwREQ1NWixi2j1Ti3mjYkyqGVY8XphWKEIIWmheqLnYCXRXhbxZ4E+FGg81ZYG8TKYC/IjzV8p0rLnAI1qS7wdwv5UJ9vQJt6KcxdHHZsUlpIfaJC6N5DvAL/qUY8DoIymgz</X509Certificate>
24+
</X509Data>
25+
</KeyInfo>
26+
</KeyDescriptor>
27+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
28+
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
29+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
30+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:entity</NameIDFormat>
31+
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
32+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos</NameIDFormat>
33+
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName</NameIDFormat>
34+
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName</NameIDFormat>
35+
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp.example.org/sso/SingleSignOnService" />
36+
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://idp.example.org/sso/SingleSignOnService" />
37+
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://idp.example.org/sso/SingleSignOnService" />
38+
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp.example.org/sso/SingleLogoutService" />
39+
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://idp.example.org/sso/SingleLogoutService" />
40+
</IDPSSODescriptor>
41+
</EntityDescriptor>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<EntityDescriptor ID="SMa4fd5378c57fa016d03c6b27a8e0cf6f99ed2073b"
2+
entityID="https://idp.example.com/metadata"
3+
xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
4+
<IDPSSODescriptor WantAuthnRequestsSigned="true"
5+
ID="SM14a93e72cb19411b4fc4eec882c98b12dbf55cea68e"
6+
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
7+
<KeyDescriptor use="signing">
8+
<ds:KeyInfo>
9+
<ds:X509Data>
10+
<ds:X509Certificate>
11+
cert 1
12+
</ds:X509Certificate>
13+
</ds:X509Data>
14+
</ds:KeyInfo>
15+
</KeyDescriptor>
16+
<KeyDescriptor>
17+
<ds:KeyInfo>
18+
<ds:X509Data>
19+
<ds:X509Certificate>
20+
cert 2
21+
</ds:X509Certificate>
22+
</ds:X509Data>
23+
</ds:KeyInfo>
24+
</KeyDescriptor>
25+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
26+
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
27+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
28+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:entity</NameIDFormat>
29+
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
30+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos</NameIDFormat>
31+
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName</NameIDFormat>
32+
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName</NameIDFormat>
33+
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
34+
Location="https://idp.example.org/sso/SingleSignOnService" />
35+
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
36+
Location="https://idp.example.org/sso/SingleSignOnService" />
37+
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"
38+
Location="https://idp.example.org/sso/SingleSignOnService" />
39+
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
40+
Location="https://idp.example.org/sso/SingleLogoutService" />
41+
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
42+
Location="https://idp.example.org/sso/SingleLogoutService" />
43+
</IDPSSODescriptor>
44+
</EntityDescriptor>

0 commit comments

Comments
 (0)