samlesa 2.16.6 → 2.17.1

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.

Files changed (82) hide show
  1. package/README.md +30 -50
  2. package/build/index.js +2 -1
  3. package/build/src/binding-artifact.js +330 -146
  4. package/build/src/binding-post.js +45 -31
  5. package/build/src/binding-redirect.js +0 -10
  6. package/build/src/binding-simplesign.js +0 -1
  7. package/build/src/entity-idp.js +1 -5
  8. package/build/src/entity-sp.js +21 -96
  9. package/build/src/extractor.js +48 -4
  10. package/build/src/flow.js +24 -166
  11. package/build/src/libsaml.js +468 -264
  12. package/build/src/libsamlSoap.js +115 -0
  13. package/build/src/schema/xml.xsd +88 -88
  14. package/build/src/schemaValidator.js +5 -13
  15. package/build/src/soap.js +123 -3
  16. package/build/src/utility.js +12 -7
  17. package/package.json +77 -81
  18. package/types/api.d.ts +15 -0
  19. package/types/api.d.ts.map +1 -0
  20. package/types/binding-post.d.ts +48 -0
  21. package/types/binding-post.d.ts.map +1 -0
  22. package/types/binding-redirect.d.ts +54 -0
  23. package/types/binding-redirect.d.ts.map +1 -0
  24. package/types/binding-simplesign.d.ts +41 -0
  25. package/types/binding-simplesign.d.ts.map +1 -0
  26. package/types/entity-idp.d.ts +38 -0
  27. package/types/entity-idp.d.ts.map +1 -0
  28. package/types/entity-sp.d.ts +38 -0
  29. package/types/entity-sp.d.ts.map +1 -0
  30. package/types/entity.d.ts +100 -0
  31. package/types/entity.d.ts.map +1 -0
  32. package/types/extractor.d.ts +26 -0
  33. package/types/extractor.d.ts.map +1 -0
  34. package/types/flow.d.ts +7 -0
  35. package/types/flow.d.ts.map +1 -0
  36. package/types/index.d.ts +2 -1
  37. package/types/index.d.ts.map +1 -1
  38. package/types/libsaml.d.ts +208 -0
  39. package/types/libsaml.d.ts.map +1 -0
  40. package/types/metadata-idp.d.ts +25 -0
  41. package/types/metadata-idp.d.ts.map +1 -0
  42. package/types/metadata-sp.d.ts +37 -0
  43. package/types/metadata-sp.d.ts.map +1 -0
  44. package/types/metadata.d.ts +58 -0
  45. package/types/metadata.d.ts.map +1 -0
  46. package/types/src/api.d.ts +3 -3
  47. package/types/src/api.d.ts.map +1 -1
  48. package/types/src/binding-artifact.d.ts +24 -29
  49. package/types/src/binding-artifact.d.ts.map +1 -1
  50. package/types/src/binding-post.d.ts +22 -22
  51. package/types/src/binding-post.d.ts.map +1 -1
  52. package/types/src/binding-redirect.d.ts.map +1 -1
  53. package/types/src/binding-simplesign.d.ts.map +1 -1
  54. package/types/src/entity-idp.d.ts +3 -4
  55. package/types/src/entity-idp.d.ts.map +1 -1
  56. package/types/src/entity-sp.d.ts +13 -24
  57. package/types/src/entity-sp.d.ts.map +1 -1
  58. package/types/src/entity.d.ts.map +1 -1
  59. package/types/src/extractor.d.ts +22 -0
  60. package/types/src/extractor.d.ts.map +1 -1
  61. package/types/src/flow.d.ts +1 -0
  62. package/types/src/flow.d.ts.map +1 -1
  63. package/types/src/libsaml.d.ts +16 -7
  64. package/types/src/libsaml.d.ts.map +1 -1
  65. package/types/src/libsamlSoap.d.ts +7 -0
  66. package/types/src/libsamlSoap.d.ts.map +1 -0
  67. package/types/src/schemaValidator.d.ts +1 -1
  68. package/types/src/schemaValidator.d.ts.map +1 -1
  69. package/types/src/soap.d.ts +33 -0
  70. package/types/src/soap.d.ts.map +1 -1
  71. package/types/src/utility.d.ts.map +1 -1
  72. package/types/src/validator.d.ts.map +1 -1
  73. package/types/types.d.ts +128 -0
  74. package/types/types.d.ts.map +1 -0
  75. package/types/urn.d.ts +195 -0
  76. package/types/urn.d.ts.map +1 -0
  77. package/types/utility.d.ts +133 -0
  78. package/types/utility.d.ts.map +1 -0
  79. package/types/validator.d.ts +4 -0
  80. package/types/validator.d.ts.map +1 -0
  81. package/build/src/schema/XMLSchema.dtd +0 -402
  82. package/build/src/schema/datatypes.dtd +0 -203
package/build/src/flow.js CHANGED
@@ -1,10 +1,6 @@
1
1
  import { base64Decode } from './utility.js';
2
2
  import { verifyTime } from './validator.js';
3
3
  import libsaml from './libsaml.js';
4
- import * as uuid from 'uuid';
5
- import { select } from 'xpath';
6
- import { DOMParser } from '@xmldom/xmldom';
7
- import { sendArtifactResolve } from "./soap.js";
8
4
  import { extract, loginRequestFields, loginResponseFields, loginResponseStatusFields, loginArtifactResponseStatusFields, logoutRequestFields, logoutResponseFields, logoutResponseStatusFields } from './extractor.js';
9
5
  import { BindingNamespace, ParserType, StatusCode, wording } from './urn.js';
10
6
  const bindDict = wording.binding;
@@ -126,58 +122,15 @@ async function redirectFlow(options) {
126
122
  }
127
123
  // proceed the post flow
128
124
  async function postFlow(options) {
129
- const { soap = false, request, from, self, parserType, checkSignature = true } = options;
125
+ const { request, from, self, parserType, checkSignature = true } = options;
130
126
  const { body } = request;
131
127
  const direction = libsaml.getQueryParamByType(parserType);
132
128
  let encodedRequest = '';
133
129
  let samlContent = '';
134
- if (soap === false) {
135
- encodedRequest = body[direction];
136
- // @ts-ignore
137
- samlContent = String(base64Decode(encodedRequest));
138
- }
130
+ encodedRequest = body[direction];
131
+ // @ts-ignore
132
+ samlContent = String(base64Decode(encodedRequest));
139
133
  /** 增加判断是不是Soap 工件绑定*/
140
- if (soap) {
141
- const metadata = {
142
- idp: from.entityMeta,
143
- sp: self.entityMeta,
144
- };
145
- const spSetting = self.entitySetting;
146
- let ID = '_' + uuid.v4();
147
- let url = metadata.idp.getArtifactResolutionService(bindDict.soap);
148
- let samlSoapRaw = libsaml.replaceTagsByValue(libsaml.defaultArtifactResolveTemplate.context, {
149
- ID: ID,
150
- Destination: url,
151
- Issuer: metadata.sp.getEntityID(),
152
- IssueInstant: new Date().toISOString(),
153
- Art: request.Art
154
- });
155
- if (!metadata.idp.isWantAuthnRequestsSigned()) {
156
- samlContent = await sendArtifactResolve(url, samlSoapRaw);
157
- }
158
- if (metadata.idp.isWantAuthnRequestsSigned()) {
159
- const { privateKey, privateKeyPass, requestSignatureAlgorithm: signatureAlgorithm, transformationAlgorithms } = spSetting;
160
- let signatureSoap = libsaml.constructSAMLSignature({
161
- referenceTagXPath: "//*[local-name(.)='ArtifactResolve']",
162
- isMessageSigned: false,
163
- isBase64Output: false,
164
- transformationAlgorithms: transformationAlgorithms,
165
- privateKey,
166
- privateKeyPass,
167
- signatureAlgorithm,
168
- rawSamlMessage: samlSoapRaw,
169
- signingCert: metadata.sp.getX509Certificate('signing'),
170
- signatureConfig: {
171
- prefix: 'ds',
172
- location: {
173
- reference: "//*[local-name(.)='Issuer']",
174
- action: 'after'
175
- }
176
- }
177
- });
178
- samlContent = await sendArtifactResolve(url, signatureSoap);
179
- }
180
- }
181
134
  const verificationOptions = {
182
135
  metadata: from.entityMeta,
183
136
  signatureAlgorithm: from.entitySetting.requestSignatureAlgorithm,
@@ -196,92 +149,26 @@ async function postFlow(options) {
196
149
  extractorFields = getDefaultExtractorFields(parserType, null);
197
150
  }
198
151
  // check status based on different scenarios
199
- await checkStatus(samlContent, parserType, soap);
152
+ await checkStatus(samlContent, parserType);
200
153
  /**检查签名顺序 */
201
- /* if (
202
- checkSignature &&
203
- from.entitySetting.messageSigningOrder === MessageSignatureOrder.ETS
204
- ) {
205
- console.log("===============我走的这里=========================")
206
- const [verified, verifiedAssertionNode,isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
207
- console.log(verified);
208
- console.log("verified")
209
- decryptRequired = isDecryptRequired
210
- if (!verified) {
211
- return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
212
- }
213
- if (!decryptRequired) {
214
- extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
215
- }
216
- }*/
217
- if (soap === true) {
218
- const [verified, verifiedAssertionNode, isDecryptRequired] = libsaml.verifySignatureSoap(samlContent, verificationOptions);
219
- decryptRequired = isDecryptRequired;
220
- if (!verified) {
221
- return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
222
- }
223
- if (!decryptRequired) {
224
- extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
225
- }
226
- if (parserType === 'SAMLResponse' && decryptRequired) {
227
- // 1. 解密断言
228
- const [decryptedSAML, decryptedAssertion] = await libsaml.decryptAssertionSoap(self, samlContent);
229
- // 2. 检查解密后的断言是否包含签名
230
- const assertionDoc = new DOMParser().parseFromString(decryptedAssertion, 'text/xml');
231
- const assertionSignatureNodes = select("./*[local-name()='Signature']", assertionDoc.documentElement);
232
- // 3. 如果存在签名则验证
233
- if (assertionSignatureNodes.length > 0) {
234
- // 3.1 创建新的验证选项(保持原配置)
235
- const assertionVerificationOptions = {
236
- ...verificationOptions,
237
- isAssertion: true // 添加标识表示正在验证断言
238
- };
239
- // 3.2 验证断言签名
240
- const [assertionVerified, result] = libsaml.verifySignatureSoap(decryptedAssertion, assertionVerificationOptions);
241
- if (!assertionVerified) {
242
- console.error("解密后的断言签名验证失败");
243
- return Promise.reject('ERR_FAIL_TO_VERIFY_ASSERTION_SIGNATURE');
244
- }
245
- if (assertionVerified) {
246
- // @ts-ignore
247
- samlContent = result;
248
- extractorFields = getDefaultExtractorFields(parserType, result);
249
- }
250
- }
251
- else {
252
- samlContent = decryptedAssertion;
253
- extractorFields = getDefaultExtractorFields(parserType, decryptedAssertion);
254
- }
255
- }
154
+ const [verified, verifiedAssertionNode, isDecryptRequired, noSignature] = libsaml.verifySignature(samlContent, verificationOptions);
155
+ decryptRequired = isDecryptRequired;
156
+ if (isDecryptRequired && noSignature) {
157
+ const result = await libsaml.decryptAssertion(self, samlContent);
158
+ samlContent = result[0];
159
+ extractorFields = getDefaultExtractorFields(parserType, result[1]);
256
160
  }
257
- if (soap === false) {
258
- const [verified, verifiedAssertionNode, isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
259
- decryptRequired = isDecryptRequired;
260
- if (!verified) {
261
- return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
262
- }
263
- if (!decryptRequired) {
264
- extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
265
- }
266
- if (parserType === 'SAMLResponse' && decryptRequired) {
267
- const result = await libsaml.decryptAssertion(self, samlContent);
268
- samlContent = result[0];
269
- extractorFields = getDefaultExtractorFields(parserType, result[1]);
270
- }
161
+ if (!verified && !noSignature && !isDecryptRequired) {
162
+ return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
163
+ }
164
+ if (!isDecryptRequired) {
165
+ extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
166
+ }
167
+ if (parserType === 'SAMLResponse' && isDecryptRequired && !noSignature) {
168
+ const result = await libsaml.decryptAssertion(self, samlContent);
169
+ samlContent = result[0];
170
+ extractorFields = getDefaultExtractorFields(parserType, result[1]);
271
171
  }
272
- // verify the signatures (the response is signed then encrypted, then decrypt first then verify)
273
- /* if (
274
- checkSignature &&
275
- from.entitySetting.messageSigningOrder === MessageSignatureOrder.STE
276
- ) {
277
- const [verified, verifiedAssertionNode,isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
278
- decryptRequired = isDecryptRequired
279
- if (verified) {
280
- extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
281
- } else {
282
- return Promise.reject('ERR_FAIL_TO_VERIFY_STE_SIGNATURE');
283
- }
284
- }*/
285
172
  const parseResult = {
286
173
  samlContent: samlContent,
287
174
  extract: extract(samlContent, extractorFields),
@@ -351,29 +238,13 @@ async function postArtifactFlow(options) {
351
238
  let decryptRequired = from.entitySetting.isAssertionEncrypted;
352
239
  let extractorFields = [];
353
240
  // validate the xml first
354
- let res = await libsaml.isValidXml(samlContent);
241
+ let res = await libsaml.isValidXml(samlContent, true);
355
242
  if (parserType !== urlParams.samlResponse) {
356
243
  extractorFields = getDefaultExtractorFields(parserType, null);
357
244
  }
358
245
  // check status based on different scenarios
359
246
  await checkStatus(samlContent, parserType);
360
247
  /**检查签名顺序 */
361
- /* if (
362
- checkSignature &&
363
- from.entitySetting.messageSigningOrder === MessageSignatureOrder.ETS
364
- ) {
365
- console.log("===============我走的这里=========================")
366
- const [verified, verifiedAssertionNode,isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
367
- console.log(verified);
368
- console.log("verified")
369
- decryptRequired = isDecryptRequired
370
- if (!verified) {
371
- return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
372
- }
373
- if (!decryptRequired) {
374
- extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
375
- }
376
- }*/
377
248
  const [verified, verifiedAssertionNode, isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
378
249
  decryptRequired = isDecryptRequired;
379
250
  if (!verified) {
@@ -387,19 +258,6 @@ async function postArtifactFlow(options) {
387
258
  samlContent = result[0];
388
259
  extractorFields = getDefaultExtractorFields(parserType, result[1]);
389
260
  }
390
- // verify the signatures (the response is signed then encrypted, then decrypt first then verify)
391
- /* if (
392
- checkSignature &&
393
- from.entitySetting.messageSigningOrder === MessageSignatureOrder.STE
394
- ) {
395
- const [verified, verifiedAssertionNode,isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
396
- decryptRequired = isDecryptRequired
397
- if (verified) {
398
- extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
399
- } else {
400
- return Promise.reject('ERR_FAIL_TO_VERIFY_STE_SIGNATURE');
401
- }
402
- }*/
403
261
  const parseResult = {
404
262
  samlContent: samlContent,
405
263
  extract: extract(samlContent, extractorFields),
@@ -469,7 +327,7 @@ async function postSimpleSignFlow(options) {
469
327
  const xmlString = String(base64Decode(encodedRequest));
470
328
  // validate the xml
471
329
  try {
472
- await libsaml.isValidXml(xmlString);
330
+ await libsaml.isValidXml(xmlString, false);
473
331
  }
474
332
  catch (e) {
475
333
  return Promise.reject('ERR_INVALID_XML');
@@ -546,7 +404,7 @@ async function postSimpleSignFlow(options) {
546
404
  }
547
405
  return Promise.resolve(parseResult);
548
406
  }
549
- function checkStatus(content, parserType, soap) {
407
+ export function checkStatus(content, parserType, soap) {
550
408
  // only check response parser
551
409
  if (parserType !== urlParams.samlResponse && parserType !== urlParams.logoutResponse) {
552
410
  return Promise.resolve('SKIPPED');