samlesa 4.7.3 → 4.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -19
- package/build/src/libsaml.js +25 -13
- package/build/src/libsamlSoap.js +59 -1
- package/package.json +1 -1
- package/types/src/libsaml.d.ts.map +1 -1
- package/types/src/libsamlSoap.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -154,25 +154,25 @@ const { context: samlResponse } = await idp.createLoginResponse({
|
|
|
154
154
|
});
|
|
155
155
|
```
|
|
156
156
|
|
|
157
|
-
### Artifact Binding Support
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
import { ServiceProvider, IdentityProvider } from 'samlesa';
|
|
161
|
-
|
|
162
|
-
// Create front-channel artifact login request
|
|
163
|
-
const loginRequest = sp.createLoginRequest(idp, 'artifact');
|
|
164
|
-
|
|
165
|
-
// Parse ArtifactResolve request on the SP artifact resolution endpoint
|
|
166
|
-
const artifactResolve = await sp.parseArtifactResolveRequest(idp, soapXml);
|
|
167
|
-
|
|
168
|
-
// Create ArtifactResponse with the resolved SAML message
|
|
169
|
-
const artifactResponse = await sp.createArtifactResolveResponse(idp, {
|
|
170
|
-
inResponseTo: artifactResolve.extract.request.id,
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
// Parse artifact-based login response from the ACS endpoint
|
|
174
|
-
const responseResult = await sp.parseLoginResponse(idp, 'artifact', request);
|
|
175
|
-
```
|
|
157
|
+
### Artifact Binding Support
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import { ServiceProvider, IdentityProvider } from 'samlesa';
|
|
161
|
+
|
|
162
|
+
// Create front-channel artifact login request
|
|
163
|
+
const loginRequest = sp.createLoginRequest(idp, 'artifact');
|
|
164
|
+
|
|
165
|
+
// Parse ArtifactResolve request on the SP artifact resolution endpoint
|
|
166
|
+
const artifactResolve = await sp.parseArtifactResolveRequest(idp, soapXml);
|
|
167
|
+
|
|
168
|
+
// Create ArtifactResponse with the resolved SAML message
|
|
169
|
+
const artifactResponse = await sp.createArtifactResolveResponse(idp, {
|
|
170
|
+
inResponseTo: artifactResolve.extract.request.id,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Parse artifact-based login response from the ACS endpoint
|
|
174
|
+
const responseResult = await sp.parseLoginResponse(idp, 'artifact', request);
|
|
175
|
+
```
|
|
176
176
|
|
|
177
177
|
---
|
|
178
178
|
|
package/build/src/libsaml.js
CHANGED
|
@@ -46,29 +46,36 @@ function resolveSignaturePublicKeys(signatureNode, metadata) {
|
|
|
46
46
|
}
|
|
47
47
|
function verifyXmlSignatureWithPublicKeys(signatureNode, xmlCandidates, publicKeys, signatureAlgorithm) {
|
|
48
48
|
let lastError = null;
|
|
49
|
+
let hasNonThrowFailure = false;
|
|
49
50
|
for (const publicKey of publicKeys) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
for (const xmlCandidate of xmlCandidates) {
|
|
52
|
+
try {
|
|
53
|
+
const sig = new SignedXml();
|
|
54
|
+
sig.publicCert = publicKey;
|
|
55
|
+
if (signatureAlgorithm) {
|
|
56
|
+
sig.signatureAlgorithm = signatureAlgorithm;
|
|
57
|
+
}
|
|
58
|
+
sig.loadSignature(signatureNode);
|
|
58
59
|
if (sig.checkSignature(xmlCandidate)) {
|
|
59
60
|
return { verified: true, sig };
|
|
60
61
|
}
|
|
62
|
+
hasNonThrowFailure = true;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
lastError = error;
|
|
61
66
|
}
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
lastError = error;
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
|
-
if (lastError && publicKeys.length === 1) {
|
|
69
|
+
if (lastError && publicKeys.length === 1 && !hasNonThrowFailure) {
|
|
68
70
|
throw lastError;
|
|
69
71
|
}
|
|
70
72
|
return { verified: false, sig: null };
|
|
71
73
|
}
|
|
74
|
+
function isInclusiveCanonicalizationSignature(signatureNode) {
|
|
75
|
+
const algorithm = select(".//*[local-name(.)='CanonicalizationMethod']/@Algorithm", signatureNode)?.value || '';
|
|
76
|
+
return algorithm === 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315' ||
|
|
77
|
+
algorithm === 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments';
|
|
78
|
+
}
|
|
72
79
|
let conList = [
|
|
73
80
|
"http://www.w3.org/2001/10/xml-exc-c14n#",
|
|
74
81
|
"http://www.w3.org/2001/10/xml-exc-c14n#WithComments",
|
|
@@ -672,7 +679,12 @@ xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="{ID}"
|
|
|
672
679
|
const assertionNode = select("/*[local-name() = 'Response' or local-name() = 'AuthnRequest']/*[local-name() = 'Assertion']", doc)[0];
|
|
673
680
|
if (assertionNode) {
|
|
674
681
|
const assertionDoc = dom.parseFromString(assertionNode.toString(), 'application/xml');
|
|
675
|
-
|
|
682
|
+
const fullDocumentXml = doc.toString();
|
|
683
|
+
const assertionXml = assertionDoc.toString();
|
|
684
|
+
const verificationCandidates = isInclusiveCanonicalizationSignature(signatureNode)
|
|
685
|
+
? [fullDocumentXml, assertionXml]
|
|
686
|
+
: [assertionXml, fullDocumentXml];
|
|
687
|
+
AssertionSignatureStatus = verifyXmlSignatureWithPublicKeys(signatureNode, verificationCandidates, publicKeys, signatureAlgorithm).verified;
|
|
676
688
|
}
|
|
677
689
|
else {
|
|
678
690
|
AssertionSignatureStatus = false;
|
package/build/src/libsamlSoap.js
CHANGED
|
@@ -15,6 +15,64 @@ function toNodeArray(result) {
|
|
|
15
15
|
}
|
|
16
16
|
return [];
|
|
17
17
|
}
|
|
18
|
+
function isElementNode(node) {
|
|
19
|
+
return !!node && node.nodeType === 1;
|
|
20
|
+
}
|
|
21
|
+
function isNamespaceDeclaration(attributeName) {
|
|
22
|
+
return attributeName === 'xmlns' || attributeName.startsWith('xmlns:');
|
|
23
|
+
}
|
|
24
|
+
function getNamespaceDeclarationMap(node) {
|
|
25
|
+
const declarations = new Map();
|
|
26
|
+
const attributes = node.attributes;
|
|
27
|
+
for (let index = 0; index < attributes.length; index += 1) {
|
|
28
|
+
const attribute = attributes.item(index);
|
|
29
|
+
if (attribute && isNamespaceDeclaration(attribute.name)) {
|
|
30
|
+
declarations.set(attribute.name, attribute.value);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return declarations;
|
|
34
|
+
}
|
|
35
|
+
function collectInheritedNamespaceDeclarations(node) {
|
|
36
|
+
const inheritedDeclarations = new Map();
|
|
37
|
+
let current = node.parentNode;
|
|
38
|
+
while (isElementNode(current)) {
|
|
39
|
+
for (const [name, value] of getNamespaceDeclarationMap(current)) {
|
|
40
|
+
if (!inheritedDeclarations.has(name)) {
|
|
41
|
+
inheritedDeclarations.set(name, value);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
current = current.parentNode;
|
|
45
|
+
}
|
|
46
|
+
return inheritedDeclarations;
|
|
47
|
+
}
|
|
48
|
+
function escapeAttributeValue(value) {
|
|
49
|
+
return value
|
|
50
|
+
.replace(/&/g, '&')
|
|
51
|
+
.replace(/"/g, '"')
|
|
52
|
+
.replace(/</g, '<')
|
|
53
|
+
.replace(/>/g, '>');
|
|
54
|
+
}
|
|
55
|
+
function rootHasNamespaceDeclaration(serializedXml, name) {
|
|
56
|
+
const rootStartTag = serializedXml.match(/^<[^>]+>/)?.[0] || '';
|
|
57
|
+
return new RegExp(`(?:^|\\s)${name.replace(':', '\\:')}\\s*=`).test(rootStartTag);
|
|
58
|
+
}
|
|
59
|
+
function serializeWithInheritedNamespaces(node) {
|
|
60
|
+
if (!isElementNode(node)) {
|
|
61
|
+
return node.toString();
|
|
62
|
+
}
|
|
63
|
+
let serializedXml = node.toString();
|
|
64
|
+
const declarationsToAdd = [];
|
|
65
|
+
for (const [name, value] of collectInheritedNamespaceDeclarations(node)) {
|
|
66
|
+
if (!rootHasNamespaceDeclaration(serializedXml, name)) {
|
|
67
|
+
declarationsToAdd.push(`${name}="${escapeAttributeValue(value)}"`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (declarationsToAdd.length === 0) {
|
|
71
|
+
return serializedXml;
|
|
72
|
+
}
|
|
73
|
+
serializedXml = serializedXml.replace(/^<([^\s/>]+)([^>]*)>/, (_match, tagName, attributes) => `<${tagName} ${declarationsToAdd.join(' ')}${attributes}>`);
|
|
74
|
+
return serializedXml;
|
|
75
|
+
}
|
|
18
76
|
const certUse = wording.certUse;
|
|
19
77
|
const docParser = new DOMParser();
|
|
20
78
|
function resolvePublicCertificates(signatureNode, opts) {
|
|
@@ -44,7 +102,7 @@ function extractResolvedMessage(rootNode) {
|
|
|
44
102
|
if (resolvedNodes.length === 0) {
|
|
45
103
|
return null;
|
|
46
104
|
}
|
|
47
|
-
return resolvedNodes[0]
|
|
105
|
+
return serializeWithInheritedNamespaces(resolvedNodes[0]);
|
|
48
106
|
}
|
|
49
107
|
function verifySignature(xml, signatureNodes, opts) {
|
|
50
108
|
for (const signatureNode of signatureNodes) {
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libsaml.d.ts","sourceRoot":"","sources":["../../src/libsaml.ts"],"names":[],"mappings":"AAQA,OAAQ,KAAK,MAAM,MAAM,aAAa,CAAA;AAItC,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"libsaml.d.ts","sourceRoot":"","sources":["../../src/libsaml.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libsamlSoap.d.ts","sourceRoot":"","sources":["../../src/libsamlSoap.ts"],"names":[],"mappings":"AAKA,OAAgB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"libsamlSoap.d.ts","sourceRoot":"","sources":["../../src/libsamlSoap.ts"],"names":[],"mappings":"AAKA,OAAgB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AA2FjE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,iBAAiB,GAAG,kBAAkB,CAAC;IAC7C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AA4HD,iBAAe,2BAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAoCpH;;;;AAED,wBAEE"}
|