samlesa 2.17.2 → 2.18.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.
Files changed (51) hide show
  1. package/build/src/binding-artifact.js +24 -14
  2. package/build/src/binding-post.js +0 -2
  3. package/build/src/flow.js +169 -27
  4. package/build/src/libsaml.js +442 -213
  5. package/build/src/metadata-idp.js +26 -24
  6. package/build/src/metadata-sp.js +19 -19
  7. package/build/src/schemaValidator.js +30 -6
  8. package/package.json +77 -78
  9. package/types/api.d.ts +15 -0
  10. package/types/api.d.ts.map +1 -0
  11. package/types/binding-post.d.ts +48 -0
  12. package/types/binding-post.d.ts.map +1 -0
  13. package/types/binding-redirect.d.ts +54 -0
  14. package/types/binding-redirect.d.ts.map +1 -0
  15. package/types/binding-simplesign.d.ts +41 -0
  16. package/types/binding-simplesign.d.ts.map +1 -0
  17. package/types/entity-idp.d.ts +38 -0
  18. package/types/entity-idp.d.ts.map +1 -0
  19. package/types/entity-sp.d.ts +38 -0
  20. package/types/entity-sp.d.ts.map +1 -0
  21. package/types/entity.d.ts +100 -0
  22. package/types/entity.d.ts.map +1 -0
  23. package/types/extractor.d.ts +26 -0
  24. package/types/extractor.d.ts.map +1 -0
  25. package/types/flow.d.ts +7 -0
  26. package/types/flow.d.ts.map +1 -0
  27. package/types/libsaml.d.ts +208 -0
  28. package/types/libsaml.d.ts.map +1 -0
  29. package/types/metadata-idp.d.ts +25 -0
  30. package/types/metadata-idp.d.ts.map +1 -0
  31. package/types/metadata-sp.d.ts +37 -0
  32. package/types/metadata-sp.d.ts.map +1 -0
  33. package/types/metadata.d.ts +58 -0
  34. package/types/metadata.d.ts.map +1 -0
  35. package/types/src/binding-artifact.d.ts.map +1 -1
  36. package/types/src/binding-post.d.ts.map +1 -1
  37. package/types/src/flow.d.ts.map +1 -1
  38. package/types/src/libsaml.d.ts +50 -1
  39. package/types/src/libsaml.d.ts.map +1 -1
  40. package/types/src/metadata-idp.d.ts.map +1 -1
  41. package/types/src/metadata-sp.d.ts.map +1 -1
  42. package/types/src/schemaValidator.d.ts +1 -1
  43. package/types/src/schemaValidator.d.ts.map +1 -1
  44. package/types/types.d.ts +128 -0
  45. package/types/types.d.ts.map +1 -0
  46. package/types/urn.d.ts +195 -0
  47. package/types/urn.d.ts.map +1 -0
  48. package/types/utility.d.ts +133 -0
  49. package/types/utility.d.ts.map +1 -0
  50. package/types/validator.d.ts +4 -0
  51. package/types/validator.d.ts.map +1 -0
@@ -383,22 +383,32 @@ async function parseLoginResponseResolve(params) {
383
383
  return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
384
384
  }
385
385
  samlContent = verifiedAssertionNode1;
386
- const [verified, verifiedAssertionNode, isDecryptRequired, noSignature] = libsaml.verifySignature(samlContent, verificationOptions);
387
- if (isDecryptRequired && noSignature) {
388
- const result = await libsaml.decryptAssertion(sp, samlContent);
389
- samlContent = result[0];
390
- extractorFields = getDefaultExtractorFields(parserType, result[1]);
391
- }
392
- if (!verified && !noSignature && !isDecryptRequired) {
393
- return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
386
+ // 改进的postFlow函数中关于签名验证的部分
387
+ const verificationResult = libsaml.verifySignature(samlContent, verificationOptions, self);
388
+ // 检查验证结果
389
+ if (!verificationResult.status) {
390
+ // 如果验证失败,根据具体情况返回错误
391
+ if (verificationResult.isMessageSigned && !verificationResult.MessageSignatureStatus) {
392
+ return Promise.reject('ERR_FAIL_TO_VERIFY_MESSAGE_SIGNATURE');
393
+ }
394
+ if (verificationResult.isAssertionSigned && !verificationResult.AssertionSignatureStatus) {
395
+ return Promise.reject('ERR_FAIL_TO_VERIFY_ASSERTION_SIGNATURE');
396
+ }
397
+ if (verificationResult.encrypted && !verificationResult.decrypted) {
398
+ return Promise.reject('ERR_FAIL_TO_DECRYPT_ASSERTION');
399
+ }
400
+ // 通用验证失败
401
+ return Promise.reject('ERR_FAIL_TO_VERIFY_SIGNATURE_OR_DECRYPTION');
394
402
  }
395
- if (!isDecryptRequired) {
396
- extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
403
+ // 更新samlContent为验证后的版本(可能已解密)
404
+ samlContent = verificationResult.samlContent;
405
+ // 根据验证结果设置extractorFields
406
+ if (verificationResult.assertionContent) {
407
+ extractorFields = getDefaultExtractorFields(parserType, verificationResult.assertionContent);
397
408
  }
398
- if (parserType === 'SAMLResponse' && isDecryptRequired && !noSignature) {
399
- const result = await libsaml.decryptAssertion(sp, samlContent);
400
- samlContent = result[0];
401
- extractorFields = getDefaultExtractorFields(parserType, result[1]);
409
+ else {
410
+ // 如果没有断言内容(例如注销请求/响应),使用适当的处理方式
411
+ extractorFields = getDefaultExtractorFields(parserType, null);
402
412
  }
403
413
  const parseResult = {
404
414
  samlContent: samlContent,
@@ -130,8 +130,6 @@ async function base64LoginResponse(requestInfo = {}, entity, user = {}, customTa
130
130
  tvalue.InResponseTo = requestInfo?.extract?.request?.id ?? '';
131
131
  }
132
132
  rawSamlResponse = libsaml.replaceTagsByValue(libsaml.defaultLoginResponseTemplate.context, tvalue);
133
- console.log(rawSamlResponse);
134
- console.log("没有加密签名过的------------------------------------");
135
133
  }
136
134
  const { privateKey, privateKeyPass, requestSignatureAlgorithm: signatureAlgorithm } = idpSetting;
137
135
  const config = {
package/build/src/flow.js CHANGED
@@ -151,23 +151,149 @@ async function postFlow(options) {
151
151
  // check status based on different scenarios
152
152
  await checkStatus(samlContent, parserType);
153
153
  /**检查签名顺序 */
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]);
160
- }
161
- if (!verified && !noSignature && !isDecryptRequired) {
162
- return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
154
+ /*
155
+ const [verified, verifiedAssertionNode, isDecryptRequired, noSignature] = libsaml.verifySignature(samlContent, verificationOptions);
156
+ decryptRequired = isDecryptRequired
157
+ if (isDecryptRequired && noSignature) {
158
+
159
+ const result = await libsaml.decryptAssertion(self, samlContent);
160
+ samlContent = result[0];
161
+ extractorFields = getDefaultExtractorFields(parserType, result[1]);
162
+ }
163
+ if (!verified && !noSignature && !isDecryptRequired) {
164
+
165
+ return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
166
+ }
167
+ if (!isDecryptRequired) {
168
+
169
+ extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
170
+ }
171
+ if (parserType === 'SAMLResponse' && isDecryptRequired && !noSignature) {
172
+ const result = await libsaml.decryptAssertion(self, samlContent);
173
+ samlContent = result[0];
174
+ extractorFields = getDefaultExtractorFields(parserType, result[1]);
175
+ console.log("走这里来了=========")
176
+ console.log(result[1])
177
+ }
178
+
179
+
180
+ const parseResult = {
181
+ samlContent: samlContent,
182
+ extract: extract(samlContent, extractorFields),
183
+ };
184
+ /!**
185
+ * Validation part: validate the context of response after signature is verified and decrypted (optional)
186
+ *!/
187
+ const targetEntityMetadata = from.entityMeta;
188
+ const issuer = targetEntityMetadata.getEntityID();
189
+ const extractedProperties = parseResult.extract;
190
+ // unmatched issuer
191
+ if (
192
+ (parserType === 'LogoutResponse' || parserType === 'SAMLResponse')
193
+ && extractedProperties
194
+ && extractedProperties.issuer !== issuer
195
+ ) {
196
+ return Promise.reject('ERR_UNMATCH_ISSUER');
197
+ }
198
+
199
+ // invalid session time
200
+ // only run the verifyTime when `SessionNotOnOrAfter` exists
201
+ if (
202
+ parserType === 'SAMLResponse'
203
+ && extractedProperties.sessionIndex.sessionNotOnOrAfter
204
+ && !verifyTime(
205
+ undefined,
206
+ extractedProperties.sessionIndex.sessionNotOnOrAfter,
207
+ self.entitySetting.clockDrifts
208
+ )
209
+ ) {
210
+ return Promise.reject('ERR_EXPIRED_SESSION');
211
+ }
212
+
213
+ // invalid time
214
+ // 2.4.1.2 https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf
215
+ if (
216
+ parserType === 'SAMLResponse'
217
+ && extractedProperties.conditions
218
+ && !verifyTime(
219
+ extractedProperties.conditions.notBefore,
220
+ extractedProperties.conditions.notOnOrAfter,
221
+ self.entitySetting.clockDrifts
222
+ )
223
+ ) {
224
+ return Promise.reject('ERR_SUBJECT_UNCONFIRMED');
225
+ }
226
+ //valid destination
227
+ //There is no validation of the response here. The upper-layer application
228
+ // should verify the result by itself to see if the destination is equal to the SP acs and
229
+ // whether the response.id is used to prevent replay attacks.
230
+ /!*
231
+ let destination = extractedProperties?.response?.destination
232
+ let isExit = self.entitySetting?.assertionConsumerService?.filter((item) => {
233
+ return item?.Location === destination
234
+ })
235
+ if (isExit?.length === 0) {
236
+ return Promise.reject('ERR_Destination_URL');
237
+ }
238
+ if (parserType === 'SAMLResponse') {
239
+ let destination = extractedProperties?.response?.destination
240
+ let isExit = self.entitySetting?.assertionConsumerService?.filter((item: { Location: any; }) => {
241
+ return item?.Location === destination
242
+ })
243
+ if (isExit?.length === 0) {
244
+ return Promise.reject('ERR_Destination_URL');
245
+ }
246
+ }
247
+ *!/
248
+
249
+
250
+ return Promise.resolve(parseResult);*/
251
+ // 改进的postFlow函数中关于签名验证的部分
252
+ const verificationResult = libsaml.verifySignature(samlContent, verificationOptions, self);
253
+ /* console.log(verificationResult)
254
+ console.log("解析对象")*/
255
+ let resultObject = {
256
+ isMessageSigned: true, //是否有外层的消息签名(Response或者Request 等最外层的签名)
257
+ MessageSignatureStatus: true, //外层的签名是否经过验证
258
+ isAssertionSigned: true, //是否有断言的签名
259
+ AssertionSignatureStatus: true, //断言签名是否经过验证
260
+ encrypted: true, //断言是否加密
261
+ decrypted: true, //断言加密后断言是否解密成功,
262
+ status: true, //是否全部通过验证,
263
+ samlContent: 'xxx', //xxx是通过验证后 解密后的整个响应,
264
+ assertionContent: 'xxx', //xxx是通过验证后 解密后的整个响应中的assertion 断言部分字符串
265
+ };
266
+ // 检查验证结果
267
+ if (!verificationResult.status) {
268
+ // 如果验证失败,根据具体情况返回错误
269
+ /** 需要判断是不是 */
270
+ if (verificationResult.isMessageSigned && !verificationResult.MessageSignatureStatus) {
271
+ return Promise.reject('ERR_FAIL_TO_VERIFY_MESSAGE_SIGNATURE');
272
+ }
273
+ if (verificationResult.isAssertionSigned && !verificationResult.AssertionSignatureStatus) {
274
+ return Promise.reject('ERR_FAIL_TO_VERIFY_ASSERTION_SIGNATURE');
275
+ }
276
+ if (verificationResult.encrypted && !verificationResult.decrypted) {
277
+ return Promise.reject('ERR_FAIL_TO_DECRYPT_ASSERTION');
278
+ }
279
+ if (!verificationResult.isMessageSigned && verificationResult.type === 'LogoutRequest') {
280
+ return Promise.reject('ERR_LogoutRequest_Need_Signature');
281
+ }
282
+ if (!verificationResult.isMessageSigned && verificationResult.type === 'LogoutResponse') {
283
+ return Promise.reject('ERR_LogoutResponse_Need_Signature');
284
+ }
285
+ // 通用验证失败
286
+ return Promise.reject('ERR_FAIL_TO_VERIFY_SIGNATURE_OR_DECRYPTION');
163
287
  }
164
- if (!isDecryptRequired) {
165
- extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
288
+ // 更新samlContent为验证后的版本(可能已解密)
289
+ samlContent = verificationResult.samlContent;
290
+ // 根据验证结果设置extractorFields
291
+ if (verificationResult.assertionContent) {
292
+ extractorFields = getDefaultExtractorFields(parserType, verificationResult.assertionContent);
166
293
  }
167
- if (parserType === 'SAMLResponse' && isDecryptRequired && !noSignature) {
168
- const result = await libsaml.decryptAssertion(self, samlContent);
169
- samlContent = result[0];
170
- extractorFields = getDefaultExtractorFields(parserType, result[1]);
294
+ else {
295
+ // 如果没有断言内容(例如注销请求/响应),使用适当的处理方式
296
+ extractorFields = getDefaultExtractorFields(parserType, null);
171
297
  }
172
298
  const parseResult = {
173
299
  samlContent: samlContent,
@@ -245,18 +371,34 @@ async function postArtifactFlow(options) {
245
371
  // check status based on different scenarios
246
372
  await checkStatus(samlContent, parserType);
247
373
  /**检查签名顺序 */
248
- const [verified, verifiedAssertionNode, isDecryptRequired] = libsaml.verifySignature(samlContent, verificationOptions);
249
- decryptRequired = isDecryptRequired;
250
- if (!verified) {
251
- return Promise.reject('ERR_FAIL_TO_VERIFY_ETS_SIGNATURE');
252
- }
253
- if (!decryptRequired) {
254
- extractorFields = getDefaultExtractorFields(parserType, verifiedAssertionNode);
255
- }
256
- if (parserType === 'SAMLResponse' && decryptRequired) {
257
- const result = await libsaml.decryptAssertion(self, samlContent);
258
- samlContent = result[0];
259
- extractorFields = getDefaultExtractorFields(parserType, result[1]);
374
+ // 改进的postFlow函数中关于签名验证的部分
375
+ const verificationResult = libsaml.verifySignature(samlContent, verificationOptions, self);
376
+ console.log(verificationResult);
377
+ console.log("最终结果====");
378
+ // 检查验证结果
379
+ if (!verificationResult.status) {
380
+ // 如果验证失败,根据具体情况返回错误
381
+ if (verificationResult.isMessageSigned && !verificationResult.MessageSignatureStatus) {
382
+ return Promise.reject('ERR_FAIL_TO_VERIFY_MESSAGE_SIGNATURE');
383
+ }
384
+ if (verificationResult.isAssertionSigned && !verificationResult.AssertionSignatureStatus) {
385
+ return Promise.reject('ERR_FAIL_TO_VERIFY_ASSERTION_SIGNATURE');
386
+ }
387
+ if (verificationResult.encrypted && !verificationResult.decrypted) {
388
+ return Promise.reject('ERR_FAIL_TO_DECRYPT_ASSERTION');
389
+ }
390
+ // 通用验证失败
391
+ return Promise.reject('ERR_FAIL_TO_VERIFY_SIGNATURE_OR_DECRYPTION');
392
+ }
393
+ // 更新samlContent为验证后的版本(可能已解密)
394
+ samlContent = verificationResult.samlContent;
395
+ // 根据验证结果设置extractorFields
396
+ if (verificationResult.assertionContent) {
397
+ extractorFields = getDefaultExtractorFields(parserType, verificationResult.assertionContent);
398
+ }
399
+ else {
400
+ // 如果没有断言内容(例如注销请求/响应),使用适当的处理方式
401
+ extractorFields = getDefaultExtractorFields(parserType, null);
260
402
  }
261
403
  const parseResult = {
262
404
  samlContent: samlContent,