samlesa 2.16.5 → 2.17.0
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.
Potentially problematic release.
This version of samlesa might be problematic. Click here for more details.
- package/README.md +30 -50
- package/build/src/binding-post.js +45 -31
- package/build/src/binding-redirect.js +88 -3
- package/build/src/binding-simplesign.js +0 -1
- package/build/src/entity-idp.js +1 -5
- package/build/src/entity-sp.js +115 -23
- package/build/src/extractor.js +29 -4
- package/build/src/flow.js +36 -103
- package/build/src/libsaml.js +172 -162
- package/build/src/metadata-sp.js +2 -0
- package/build/src/metadata.js +0 -2
- package/build/src/schema/saml-schema-ecp-2.0.xsd +1 -1
- package/build/src/schema/saml-schema-metadata-2.0.xsd +3 -3
- package/build/src/schema/saml-schema-protocol-2.0.xsd +1 -1
- package/build/src/schema/{env.xsd → soap-envelope.xsd} +1 -33
- package/build/src/schema/xml.xsd +88 -0
- package/build/src/schemaValidator.js +29 -12
- package/build/src/utility.js +12 -7
- package/package.json +14 -20
- package/types/src/api.d.ts +3 -3
- package/types/src/api.d.ts.map +1 -1
- package/types/src/binding-post.d.ts +22 -22
- package/types/src/binding-post.d.ts.map +1 -1
- package/types/src/binding-redirect.d.ts +14 -1
- package/types/src/binding-redirect.d.ts.map +1 -1
- package/types/src/binding-simplesign.d.ts.map +1 -1
- package/types/src/entity-idp.d.ts +3 -4
- package/types/src/entity-idp.d.ts.map +1 -1
- package/types/src/entity-sp.d.ts +44 -21
- package/types/src/entity-sp.d.ts.map +1 -1
- package/types/src/entity.d.ts.map +1 -1
- package/types/src/extractor.d.ts +5 -0
- package/types/src/extractor.d.ts.map +1 -1
- package/types/src/flow.d.ts.map +1 -1
- package/types/src/libsaml.d.ts +15 -4
- package/types/src/libsaml.d.ts.map +1 -1
- package/types/src/metadata-sp.d.ts.map +1 -1
- package/types/src/metadata.d.ts.map +1 -1
- package/types/src/schemaValidator.d.ts +1 -1
- package/types/src/schemaValidator.d.ts.map +1 -1
- package/types/src/utility.d.ts.map +1 -1
- package/build/index.js.map +0 -1
- package/build/src/api.js.map +0 -1
- package/build/src/binding-post.js.map +0 -1
- package/build/src/binding-redirect.js.map +0 -1
- package/build/src/binding-simplesign.js.map +0 -1
- package/build/src/entity-idp.js.map +0 -1
- package/build/src/entity-sp.js.map +0 -1
- package/build/src/entity.js.map +0 -1
- package/build/src/extractor.js.map +0 -1
- package/build/src/flow.js.map +0 -1
- package/build/src/libsaml.js.map +0 -1
- package/build/src/metadata-idp.js.map +0 -1
- package/build/src/metadata-sp.js.map +0 -1
- package/build/src/metadata.js.map +0 -1
- package/build/src/types.js.map +0 -1
- package/build/src/urn.js.map +0 -1
- package/build/src/utility.js.map +0 -1
- package/build/src/validator.js.map +0 -1
package/build/src/extractor.js
CHANGED
|
@@ -68,6 +68,19 @@ export const loginResponseStatusFields = [
|
|
|
68
68
|
}
|
|
69
69
|
];
|
|
70
70
|
// support two-tiers status code
|
|
71
|
+
export const loginArtifactResponseStatusFields = [
|
|
72
|
+
{
|
|
73
|
+
key: 'top',
|
|
74
|
+
localPath: ['Envelope', 'Body', 'ArtifactResponse', 'Status', 'StatusCode'],
|
|
75
|
+
attributes: ['Value'],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
key: 'second',
|
|
79
|
+
localPath: ['Envelope', 'Body', 'ArtifactResponse', 'Status', 'StatusCode', 'StatusCode'],
|
|
80
|
+
attributes: ['Value'],
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
// support two-tiers status code
|
|
71
84
|
export const logoutResponseStatusFields = [
|
|
72
85
|
{
|
|
73
86
|
key: 'top',
|
|
@@ -178,7 +191,7 @@ export const logoutResponseFields = [
|
|
|
178
191
|
];
|
|
179
192
|
export function extract(context, fields) {
|
|
180
193
|
const { dom } = getContext();
|
|
181
|
-
const rootDoc = dom.parseFromString(context);
|
|
194
|
+
const rootDoc = dom.parseFromString(context, 'application/xml');
|
|
182
195
|
return fields.reduce((result, field) => {
|
|
183
196
|
// get essential fields
|
|
184
197
|
const key = field.key;
|
|
@@ -194,7 +207,7 @@ export function extract(context, fields) {
|
|
|
194
207
|
// if shortcut is used, then replace the doc
|
|
195
208
|
// it's a design for overriding the doc used during runtime
|
|
196
209
|
if (shortcut) {
|
|
197
|
-
targetDoc = dom.parseFromString(shortcut);
|
|
210
|
+
targetDoc = dom.parseFromString(shortcut, 'application/xml');
|
|
198
211
|
}
|
|
199
212
|
// special case: multiple path
|
|
200
213
|
/*
|
|
@@ -216,6 +229,7 @@ export function extract(context, fields) {
|
|
|
216
229
|
.join(' | ');
|
|
217
230
|
return {
|
|
218
231
|
...result,
|
|
232
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
219
233
|
[key]: uniq(select(multiXPaths, targetDoc).map((n) => n.nodeValue).filter(notEmpty))
|
|
220
234
|
};
|
|
221
235
|
}
|
|
@@ -236,8 +250,10 @@ export function extract(context, fields) {
|
|
|
236
250
|
// find the index in localpath
|
|
237
251
|
const indexPath = buildAttributeXPath(index);
|
|
238
252
|
const fullLocalXPath = `${baseXPath}${indexPath}`;
|
|
253
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
239
254
|
const parentNodes = select(baseXPath, targetDoc);
|
|
240
255
|
// [uid, mail, edupersonaffiliation], ready for aggregate
|
|
256
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
241
257
|
const parentAttributes = select(fullLocalXPath, targetDoc).map((n) => n.value);
|
|
242
258
|
// [attribute, attributevalue]
|
|
243
259
|
const childXPath = buildAbsoluteXPath([last(localPath)].concat(attributePath));
|
|
@@ -245,8 +261,9 @@ export function extract(context, fields) {
|
|
|
245
261
|
const fullChildXPath = `${childXPath}${childAttributeXPath}`;
|
|
246
262
|
// [ 'test', 'test@example.com', [ 'users', 'examplerole1' ] ]
|
|
247
263
|
const childAttributes = parentNodes.map(node => {
|
|
248
|
-
const nodeDoc = dom.parseFromString(node.toString());
|
|
264
|
+
const nodeDoc = dom.parseFromString(node.toString(), 'application/xml');
|
|
249
265
|
if (attributes.length === 0) {
|
|
266
|
+
// @ts-ignore
|
|
250
267
|
const childValues = select(fullChildXPath, nodeDoc).map((n) => n.nodeValue);
|
|
251
268
|
if (childValues.length === 1) {
|
|
252
269
|
return childValues[0];
|
|
@@ -254,6 +271,7 @@ export function extract(context, fields) {
|
|
|
254
271
|
return childValues;
|
|
255
272
|
}
|
|
256
273
|
if (attributes.length > 0) {
|
|
274
|
+
// @ts-ignore
|
|
257
275
|
const childValues = select(fullChildXPath, nodeDoc).map((n) => n.value);
|
|
258
276
|
if (childValues.length === 1) {
|
|
259
277
|
return childValues[0];
|
|
@@ -279,6 +297,7 @@ export function extract(context, fields) {
|
|
|
279
297
|
}
|
|
280
298
|
*/
|
|
281
299
|
if (isEntire) {
|
|
300
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
282
301
|
const node = select(baseXPath, targetDoc);
|
|
283
302
|
let value = null;
|
|
284
303
|
if (node.length === 1) {
|
|
@@ -301,10 +320,13 @@ export function extract(context, fields) {
|
|
|
301
320
|
}
|
|
302
321
|
*/
|
|
303
322
|
if (attributes.length > 1) {
|
|
323
|
+
// @ts-ignore
|
|
304
324
|
const baseNode = select(baseXPath, targetDoc).map(n => n.toString());
|
|
305
325
|
const childXPath = `${buildAbsoluteXPath([last(localPath)])}${attributeXPath}`;
|
|
306
326
|
const attributeValues = baseNode.map((node) => {
|
|
307
|
-
|
|
327
|
+
// @ts-ignore
|
|
328
|
+
const nodeDoc = dom.parseFromString(node, 'application/xml');
|
|
329
|
+
// @ts-ignore
|
|
308
330
|
const values = select(childXPath, nodeDoc).reduce((r, n) => {
|
|
309
331
|
r[camelCase(n.name, { locale: 'en-us' })] = n.value;
|
|
310
332
|
return r;
|
|
@@ -326,6 +348,7 @@ export function extract(context, fields) {
|
|
|
326
348
|
*/
|
|
327
349
|
if (attributes.length === 1) {
|
|
328
350
|
const fullPath = `${baseXPath}${attributeXPath}`;
|
|
351
|
+
// @ts-ignore
|
|
329
352
|
const attributeValues = select(fullPath, targetDoc).map((n) => n.value);
|
|
330
353
|
return {
|
|
331
354
|
...result,
|
|
@@ -342,9 +365,11 @@ export function extract(context, fields) {
|
|
|
342
365
|
*/
|
|
343
366
|
if (attributes.length === 0) {
|
|
344
367
|
let attributeValue = null;
|
|
368
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
345
369
|
const node = select(baseXPath, targetDoc);
|
|
346
370
|
if (node.length === 1) {
|
|
347
371
|
const fullPath = `string(${baseXPath}${attributeXPath})`;
|
|
372
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
348
373
|
attributeValue = select(fullPath, targetDoc);
|
|
349
374
|
}
|
|
350
375
|
if (node.length > 1) {
|
package/build/src/flow.js
CHANGED
|
@@ -5,8 +5,8 @@ import * as uuid from 'uuid';
|
|
|
5
5
|
import { select } from 'xpath';
|
|
6
6
|
import { DOMParser } from '@xmldom/xmldom';
|
|
7
7
|
import { sendArtifactResolve } from "./soap.js";
|
|
8
|
-
import { extract, loginRequestFields, loginResponseFields, logoutRequestFields, logoutResponseFields, logoutResponseStatusFields
|
|
9
|
-
import { BindingNamespace, ParserType,
|
|
8
|
+
import { extract, loginRequestFields, loginResponseFields, loginResponseStatusFields, loginArtifactResponseStatusFields, logoutRequestFields, logoutResponseFields, logoutResponseStatusFields } from './extractor.js';
|
|
9
|
+
import { BindingNamespace, ParserType, StatusCode, wording } from './urn.js';
|
|
10
10
|
const bindDict = wording.binding;
|
|
11
11
|
const urlParams = wording.urlParams;
|
|
12
12
|
// get the default extractor fields based on the parserType
|
|
@@ -131,7 +131,7 @@ async function postFlow(options) {
|
|
|
131
131
|
const direction = libsaml.getQueryParamByType(parserType);
|
|
132
132
|
let encodedRequest = '';
|
|
133
133
|
let samlContent = '';
|
|
134
|
-
if (soap
|
|
134
|
+
if (!soap) {
|
|
135
135
|
encodedRequest = body[direction];
|
|
136
136
|
// @ts-ignore
|
|
137
137
|
samlContent = String(base64Decode(encodedRequest));
|
|
@@ -146,12 +146,15 @@ async function postFlow(options) {
|
|
|
146
146
|
let ID = '_' + uuid.v4();
|
|
147
147
|
let url = metadata.idp.getArtifactResolutionService(bindDict.soap);
|
|
148
148
|
let samlSoapRaw = libsaml.replaceTagsByValue(libsaml.defaultArtifactResolveTemplate.context, {
|
|
149
|
-
ID:
|
|
149
|
+
ID: ID,
|
|
150
150
|
Destination: url,
|
|
151
151
|
Issuer: metadata.sp.getEntityID(),
|
|
152
152
|
IssueInstant: new Date().toISOString(),
|
|
153
153
|
Art: request.Art
|
|
154
154
|
});
|
|
155
|
+
if (!metadata.idp.isWantAuthnRequestsSigned()) {
|
|
156
|
+
samlContent = await sendArtifactResolve(url, samlSoapRaw);
|
|
157
|
+
}
|
|
155
158
|
if (metadata.idp.isWantAuthnRequestsSigned()) {
|
|
156
159
|
const { privateKey, privateKeyPass, requestSignatureAlgorithm: signatureAlgorithm, transformationAlgorithms } = spSetting;
|
|
157
160
|
let signatureSoap = libsaml.constructSAMLSignature({
|
|
@@ -172,14 +175,8 @@ async function postFlow(options) {
|
|
|
172
175
|
}
|
|
173
176
|
}
|
|
174
177
|
});
|
|
175
|
-
|
|
176
|
-
/* console.log(signatureSoap)
|
|
177
|
-
console.log("签过名的")*/
|
|
178
|
-
console.log(data);
|
|
179
|
-
console.log("keycloak数据----------------------");
|
|
180
|
-
samlContent = data;
|
|
178
|
+
samlContent = await sendArtifactResolve(url, signatureSoap);
|
|
181
179
|
}
|
|
182
|
-
// No need to embeded XML signature
|
|
183
180
|
}
|
|
184
181
|
const verificationOptions = {
|
|
185
182
|
metadata: from.entityMeta,
|
|
@@ -189,57 +186,33 @@ async function postFlow(options) {
|
|
|
189
186
|
let decryptRequired = from.entitySetting.isAssertionEncrypted;
|
|
190
187
|
let extractorFields = [];
|
|
191
188
|
// validate the xml first
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
console.log("验证和结果-----------------------")
|
|
199
|
-
console.log("验证和结果-----------------------")
|
|
200
|
-
console.log("验证和结果-----------------------")
|
|
201
|
-
});
|
|
202
|
-
console.log(res);
|
|
203
|
-
console.log("验证和结果-----------------------")*/
|
|
189
|
+
let res = await libsaml.isValidXml(samlContent, soap).catch((error) => {
|
|
190
|
+
return Promise.reject('ERR_EXCEPTION_VALIDATE_XML');
|
|
191
|
+
});
|
|
192
|
+
if (res !== true) {
|
|
193
|
+
return Promise.reject('ERR_EXCEPTION_VALIDATE_XML');
|
|
194
|
+
}
|
|
204
195
|
if (parserType !== urlParams.samlResponse) {
|
|
205
196
|
extractorFields = getDefaultExtractorFields(parserType, null);
|
|
206
197
|
}
|
|
207
198
|
// check status based on different scenarios
|
|
208
|
-
|
|
199
|
+
await checkStatus(samlContent, parserType, soap);
|
|
209
200
|
/**检查签名顺序 */
|
|
210
|
-
|
|
211
|
-
checkSignature &&
|
|
212
|
-
from.entitySetting.messageSigningOrder === MessageSignatureOrder.ETS
|
|
213
|
-
) {
|
|
214
|
-
console.log("===============我走的这里=========================")
|
|
215
|
-
const [verified, verifiedAssertionNode,isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
|
|
216
|
-
console.log(verified);
|
|
217
|
-
console.log("verified")
|
|
218
|
-
decryptRequired = isDecryptRequired
|
|
219
|
-
if (!verified) {
|
|
220
|
-
return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
|
|
221
|
-
}
|
|
222
|
-
if (!decryptRequired) {
|
|
223
|
-
extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
|
|
224
|
-
}
|
|
225
|
-
}*/
|
|
226
|
-
if (soap === true) {
|
|
201
|
+
if (soap) {
|
|
227
202
|
const [verified, verifiedAssertionNode, isDecryptRequired] = libsaml.verifySignatureSoap(samlContent, verificationOptions);
|
|
228
203
|
decryptRequired = isDecryptRequired;
|
|
229
204
|
if (!verified) {
|
|
230
205
|
return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
|
|
231
206
|
}
|
|
232
207
|
if (!decryptRequired) {
|
|
233
|
-
console.log("-------------------走到了这里----------------------");
|
|
234
208
|
extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
|
|
235
209
|
}
|
|
236
210
|
if (parserType === 'SAMLResponse' && decryptRequired) {
|
|
237
211
|
// 1. 解密断言
|
|
238
212
|
const [decryptedSAML, decryptedAssertion] = await libsaml.decryptAssertionSoap(self, samlContent);
|
|
239
|
-
console.log(decryptedAssertion);
|
|
240
|
-
console.log("解密数据-----------------------------");
|
|
241
213
|
// 2. 检查解密后的断言是否包含签名
|
|
242
|
-
const assertionDoc = new DOMParser().parseFromString(decryptedAssertion, '
|
|
214
|
+
const assertionDoc = new DOMParser().parseFromString(decryptedAssertion, 'application/xml');
|
|
215
|
+
// @ts-ignore
|
|
243
216
|
const assertionSignatureNodes = select("./*[local-name()='Signature']", assertionDoc.documentElement);
|
|
244
217
|
// 3. 如果存在签名则验证
|
|
245
218
|
if (assertionSignatureNodes.length > 0) {
|
|
@@ -250,11 +223,7 @@ async function postFlow(options) {
|
|
|
250
223
|
};
|
|
251
224
|
// 3.2 验证断言签名
|
|
252
225
|
const [assertionVerified, result] = libsaml.verifySignatureSoap(decryptedAssertion, assertionVerificationOptions);
|
|
253
|
-
console.log(assertionVerified);
|
|
254
|
-
console.log(result);
|
|
255
|
-
console.log("验证机结果--------------");
|
|
256
226
|
if (!assertionVerified) {
|
|
257
|
-
console.error("解密后的断言签名验证失败");
|
|
258
227
|
return Promise.reject('ERR_FAIL_TO_VERIFY_ASSERTION_SIGNATURE');
|
|
259
228
|
}
|
|
260
229
|
if (assertionVerified) {
|
|
@@ -269,34 +238,26 @@ async function postFlow(options) {
|
|
|
269
238
|
}
|
|
270
239
|
}
|
|
271
240
|
}
|
|
272
|
-
if (soap
|
|
273
|
-
const [verified, verifiedAssertionNode, isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
|
|
241
|
+
if (!soap) {
|
|
242
|
+
const [verified, verifiedAssertionNode, isDecryptRequired, noSignature] = libsaml.verifySignature(samlContent, verificationOptions);
|
|
274
243
|
decryptRequired = isDecryptRequired;
|
|
275
|
-
if (
|
|
244
|
+
if (isDecryptRequired && noSignature) {
|
|
245
|
+
const result = await libsaml.decryptAssertion(self, samlContent);
|
|
246
|
+
samlContent = result[0];
|
|
247
|
+
extractorFields = getDefaultExtractorFields(parserType, result[1]);
|
|
248
|
+
}
|
|
249
|
+
if (!verified && !noSignature && !isDecryptRequired) {
|
|
276
250
|
return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
|
|
277
251
|
}
|
|
278
252
|
if (!decryptRequired) {
|
|
279
253
|
extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
|
|
280
254
|
}
|
|
281
|
-
if (parserType === 'SAMLResponse' && decryptRequired) {
|
|
255
|
+
if (parserType === 'SAMLResponse' && decryptRequired && !noSignature) {
|
|
282
256
|
const result = await libsaml.decryptAssertion(self, samlContent);
|
|
283
257
|
samlContent = result[0];
|
|
284
258
|
extractorFields = getDefaultExtractorFields(parserType, result[1]);
|
|
285
259
|
}
|
|
286
260
|
}
|
|
287
|
-
// verify the signatures (the response is signed then encrypted, then decrypt first then verify)
|
|
288
|
-
/* if (
|
|
289
|
-
checkSignature &&
|
|
290
|
-
from.entitySetting.messageSigningOrder === MessageSignatureOrder.STE
|
|
291
|
-
) {
|
|
292
|
-
const [verified, verifiedAssertionNode,isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
|
|
293
|
-
decryptRequired = isDecryptRequired
|
|
294
|
-
if (verified) {
|
|
295
|
-
extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
|
|
296
|
-
} else {
|
|
297
|
-
return Promise.reject('ERR_FAIL_TO_VERIFY_STE_SIGNATURE');
|
|
298
|
-
}
|
|
299
|
-
}*/
|
|
300
261
|
const parseResult = {
|
|
301
262
|
samlContent: samlContent,
|
|
302
263
|
extract: extract(samlContent, extractorFields),
|
|
@@ -307,10 +268,6 @@ async function postFlow(options) {
|
|
|
307
268
|
const targetEntityMetadata = from.entityMeta;
|
|
308
269
|
const issuer = targetEntityMetadata.getEntityID();
|
|
309
270
|
const extractedProperties = parseResult.extract;
|
|
310
|
-
console.log(extractedProperties);
|
|
311
|
-
console.log(parseResult);
|
|
312
|
-
console.log("解析结果----------------------------------");
|
|
313
|
-
console.log("签发这-----------");
|
|
314
271
|
// unmatched issuer
|
|
315
272
|
if ((parserType === 'LogoutResponse' || parserType === 'SAMLResponse')
|
|
316
273
|
&& extractedProperties
|
|
@@ -370,29 +327,13 @@ async function postArtifactFlow(options) {
|
|
|
370
327
|
let decryptRequired = from.entitySetting.isAssertionEncrypted;
|
|
371
328
|
let extractorFields = [];
|
|
372
329
|
// validate the xml first
|
|
373
|
-
let res = await libsaml.isValidXml(samlContent);
|
|
330
|
+
let res = await libsaml.isValidXml(samlContent, true);
|
|
374
331
|
if (parserType !== urlParams.samlResponse) {
|
|
375
332
|
extractorFields = getDefaultExtractorFields(parserType, null);
|
|
376
333
|
}
|
|
377
334
|
// check status based on different scenarios
|
|
378
335
|
await checkStatus(samlContent, parserType);
|
|
379
336
|
/**检查签名顺序 */
|
|
380
|
-
/* if (
|
|
381
|
-
checkSignature &&
|
|
382
|
-
from.entitySetting.messageSigningOrder === MessageSignatureOrder.ETS
|
|
383
|
-
) {
|
|
384
|
-
console.log("===============我走的这里=========================")
|
|
385
|
-
const [verified, verifiedAssertionNode,isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
|
|
386
|
-
console.log(verified);
|
|
387
|
-
console.log("verified")
|
|
388
|
-
decryptRequired = isDecryptRequired
|
|
389
|
-
if (!verified) {
|
|
390
|
-
return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
|
|
391
|
-
}
|
|
392
|
-
if (!decryptRequired) {
|
|
393
|
-
extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
|
|
394
|
-
}
|
|
395
|
-
}*/
|
|
396
337
|
const [verified, verifiedAssertionNode, isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
|
|
397
338
|
decryptRequired = isDecryptRequired;
|
|
398
339
|
if (!verified) {
|
|
@@ -406,19 +347,6 @@ async function postArtifactFlow(options) {
|
|
|
406
347
|
samlContent = result[0];
|
|
407
348
|
extractorFields = getDefaultExtractorFields(parserType, result[1]);
|
|
408
349
|
}
|
|
409
|
-
// verify the signatures (the response is signed then encrypted, then decrypt first then verify)
|
|
410
|
-
/* if (
|
|
411
|
-
checkSignature &&
|
|
412
|
-
from.entitySetting.messageSigningOrder === MessageSignatureOrder.STE
|
|
413
|
-
) {
|
|
414
|
-
const [verified, verifiedAssertionNode,isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
|
|
415
|
-
decryptRequired = isDecryptRequired
|
|
416
|
-
if (verified) {
|
|
417
|
-
extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
|
|
418
|
-
} else {
|
|
419
|
-
return Promise.reject('ERR_FAIL_TO_VERIFY_STE_SIGNATURE');
|
|
420
|
-
}
|
|
421
|
-
}*/
|
|
422
350
|
const parseResult = {
|
|
423
351
|
samlContent: samlContent,
|
|
424
352
|
extract: extract(samlContent, extractorFields),
|
|
@@ -488,7 +416,7 @@ async function postSimpleSignFlow(options) {
|
|
|
488
416
|
const xmlString = String(base64Decode(encodedRequest));
|
|
489
417
|
// validate the xml
|
|
490
418
|
try {
|
|
491
|
-
await libsaml.isValidXml(xmlString);
|
|
419
|
+
await libsaml.isValidXml(xmlString, false);
|
|
492
420
|
}
|
|
493
421
|
catch (e) {
|
|
494
422
|
return Promise.reject('ERR_INVALID_XML');
|
|
@@ -565,14 +493,19 @@ async function postSimpleSignFlow(options) {
|
|
|
565
493
|
}
|
|
566
494
|
return Promise.resolve(parseResult);
|
|
567
495
|
}
|
|
568
|
-
function checkStatus(content, parserType) {
|
|
496
|
+
function checkStatus(content, parserType, soap) {
|
|
569
497
|
// only check response parser
|
|
570
498
|
if (parserType !== urlParams.samlResponse && parserType !== urlParams.logoutResponse) {
|
|
571
499
|
return Promise.resolve('SKIPPED');
|
|
572
500
|
}
|
|
573
|
-
|
|
501
|
+
let fields = parserType === urlParams.samlResponse
|
|
574
502
|
? loginResponseStatusFields
|
|
575
503
|
: logoutResponseStatusFields;
|
|
504
|
+
if (soap === true) {
|
|
505
|
+
fields = parserType === urlParams.samlResponse
|
|
506
|
+
? loginArtifactResponseStatusFields
|
|
507
|
+
: logoutResponseStatusFields;
|
|
508
|
+
}
|
|
576
509
|
const { top, second } = extract(content, fields);
|
|
577
510
|
// only resolve when top-tier status code is success
|
|
578
511
|
if (top === StatusCode.Success) {
|