samlesa 2.14.6 → 2.14.8

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 (116) hide show
  1. package/README.md +98 -24
  2. package/build/index.js +0 -1
  3. package/build/src/api.js +2 -2
  4. package/build/src/binding-post.js +0 -1
  5. package/build/src/binding-redirect.js +0 -1
  6. package/build/src/binding-simplesign.js +0 -1
  7. package/build/src/entity-idp.js +0 -1
  8. package/build/src/entity-sp.js +0 -1
  9. package/build/src/entity.js +0 -1
  10. package/build/src/extractor.js +0 -1
  11. package/build/src/flow.js +0 -1
  12. package/build/src/libsaml.js +0 -74
  13. package/build/src/metadata-idp.js +0 -1
  14. package/build/src/metadata-sp.js +0 -1
  15. package/build/src/metadata.js +0 -1
  16. package/build/src/schema/XMLSchema.dtd +402 -0
  17. package/build/src/schema/datatypes.dtd +203 -0
  18. package/build/src/schema/saml-schema-assertion-2.0.xsd +283 -0
  19. package/build/src/schema/saml-schema-authn-context-2.0.xsd +23 -0
  20. package/build/src/schema/saml-schema-authn-context-auth-telephony-2.0.xsd +81 -0
  21. package/build/src/schema/saml-schema-authn-context-ip-2.0.xsd +65 -0
  22. package/build/src/schema/saml-schema-authn-context-ippword-2.0.xsd +67 -0
  23. package/build/src/schema/saml-schema-authn-context-kerberos-2.0.xsd +83 -0
  24. package/build/src/schema/saml-schema-authn-context-mobileonefactor-reg-2.0.xsd +186 -0
  25. package/build/src/schema/saml-schema-authn-context-mobileonefactor-unreg-2.0.xsd +183 -0
  26. package/build/src/schema/saml-schema-authn-context-mobiletwofactor-reg-2.0.xsd +202 -0
  27. package/build/src/schema/saml-schema-authn-context-mobiletwofactor-unreg-2.0.xsd +200 -0
  28. package/build/src/schema/saml-schema-authn-context-nomad-telephony-2.0.xsd +81 -0
  29. package/build/src/schema/saml-schema-authn-context-personal-telephony-2.0.xsd +80 -0
  30. package/build/src/schema/saml-schema-authn-context-pgp-2.0.xsd +83 -0
  31. package/build/src/schema/saml-schema-authn-context-ppt-2.0.xsd +81 -0
  32. package/build/src/schema/saml-schema-authn-context-pword-2.0.xsd +64 -0
  33. package/build/src/schema/saml-schema-authn-context-session-2.0.xsd +64 -0
  34. package/build/src/schema/saml-schema-authn-context-smartcard-2.0.xsd +64 -0
  35. package/build/src/schema/saml-schema-authn-context-smartcardpki-2.0.xsd +129 -0
  36. package/build/src/schema/saml-schema-authn-context-softwarepki-2.0.xsd +129 -0
  37. package/build/src/schema/saml-schema-authn-context-spki-2.0.xsd +83 -0
  38. package/build/src/schema/saml-schema-authn-context-srp-2.0.xsd +82 -0
  39. package/build/src/schema/saml-schema-authn-context-sslcert-2.0.xsd +97 -0
  40. package/build/src/schema/saml-schema-authn-context-telephony-2.0.xsd +79 -0
  41. package/build/src/schema/saml-schema-authn-context-timesync-2.0.xsd +105 -0
  42. package/build/src/schema/saml-schema-authn-context-types-2.0.xsd +821 -0
  43. package/build/src/schema/saml-schema-authn-context-x509-2.0.xsd +83 -0
  44. package/build/src/schema/saml-schema-authn-context-xmldsig-2.0.xsd +83 -0
  45. package/build/src/schema/saml-schema-dce-2.0.xsd +29 -0
  46. package/build/src/schema/saml-schema-ecp-2.0.xsd +57 -0
  47. package/build/src/schema/saml-schema-metadata-2.0.xsd +337 -0
  48. package/build/src/schema/saml-schema-protocol-2.0.xsd +302 -0
  49. package/build/src/schema/saml-schema-x500-2.0.xsd +20 -0
  50. package/build/src/schema/saml-schema-xacml-2.0.xsd +19 -0
  51. package/build/src/schema/xenc-schema.xsd +145 -0
  52. package/build/src/schema/xmldsig-core-schema.xsd +317 -0
  53. package/build/src/schemaValidator.js +40 -0
  54. package/build/src/types.js +0 -1
  55. package/build/src/urn.js +0 -1
  56. package/build/src/utility.js +0 -1
  57. package/build/src/validator.js +0 -1
  58. package/package.json +80 -75
  59. package/types/api.d.ts +15 -0
  60. package/types/api.d.ts.map +1 -0
  61. package/types/binding-post.d.ts +48 -0
  62. package/types/binding-post.d.ts.map +1 -0
  63. package/types/binding-redirect.d.ts +54 -0
  64. package/types/binding-redirect.d.ts.map +1 -0
  65. package/types/binding-simplesign.d.ts +41 -0
  66. package/types/binding-simplesign.d.ts.map +1 -0
  67. package/types/entity-idp.d.ts +38 -0
  68. package/types/entity-idp.d.ts.map +1 -0
  69. package/types/entity-sp.d.ts +38 -0
  70. package/types/entity-sp.d.ts.map +1 -0
  71. package/types/entity.d.ts +100 -0
  72. package/types/entity.d.ts.map +1 -0
  73. package/types/extractor.d.ts +26 -0
  74. package/types/extractor.d.ts.map +1 -0
  75. package/types/flow.d.ts +7 -0
  76. package/types/flow.d.ts.map +1 -0
  77. package/types/libsaml.d.ts +208 -0
  78. package/types/libsaml.d.ts.map +1 -0
  79. package/types/metadata-idp.d.ts +25 -0
  80. package/types/metadata-idp.d.ts.map +1 -0
  81. package/types/metadata-sp.d.ts +37 -0
  82. package/types/metadata-sp.d.ts.map +1 -0
  83. package/types/metadata.d.ts +58 -0
  84. package/types/metadata.d.ts.map +1 -0
  85. package/types/src/api.d.ts.map +1 -1
  86. package/types/src/libsaml.d.ts +0 -1
  87. package/types/src/libsaml.d.ts.map +1 -1
  88. package/types/src/schemaValidator.d.ts +2 -0
  89. package/types/src/schemaValidator.d.ts.map +1 -0
  90. package/types/src/utility.d.ts.map +1 -1
  91. package/types/types.d.ts +128 -0
  92. package/types/types.d.ts.map +1 -0
  93. package/types/urn.d.ts +195 -0
  94. package/types/urn.d.ts.map +1 -0
  95. package/types/utility.d.ts +133 -0
  96. package/types/utility.d.ts.map +1 -0
  97. package/types/validator.d.ts +4 -0
  98. package/types/validator.d.ts.map +1 -0
  99. package/build/index.js.map +0 -1
  100. package/build/src/api.js.map +0 -1
  101. package/build/src/binding-post.js.map +0 -1
  102. package/build/src/binding-redirect.js.map +0 -1
  103. package/build/src/binding-simplesign.js.map +0 -1
  104. package/build/src/entity-idp.js.map +0 -1
  105. package/build/src/entity-sp.js.map +0 -1
  106. package/build/src/entity.js.map +0 -1
  107. package/build/src/extractor.js.map +0 -1
  108. package/build/src/flow.js.map +0 -1
  109. package/build/src/libsaml.js.map +0 -1
  110. package/build/src/metadata-idp.js.map +0 -1
  111. package/build/src/metadata-sp.js.map +0 -1
  112. package/build/src/metadata.js.map +0 -1
  113. package/build/src/types.js.map +0 -1
  114. package/build/src/urn.js.map +0 -1
  115. package/build/src/utility.js.map +0 -1
  116. package/build/src/validator.js.map +0 -1
package/README.md CHANGED
@@ -5,51 +5,125 @@ Highly configurable Node.js SAML 2.0 library for Single Sign On
5
5
 
6
6
  ---
7
7
 
8
- ## 🔄 本仓库为 [samlify](https://github.com/tngan/samlify) 的改进分支
9
-
10
- ## 🔄 This repository is a fork of [samlify](https://github.com/tngan/samlify) with the following improvements:
8
+ ## 🔄 本仓库为 [samlify](https://github.com/tngan/samlify) 的改进分支版本,原作者[tngan](https://github.com/tngan)
11
9
 
12
10
  ### 主要改进 / Key Improvements
13
- - ✅ 将依赖包 `@authenio/xml-encryption` 替换为 `xml-encryption` 并升级版本,支持 SHA-256/512 加密和 OAEP 摘要方法
14
- ✅ Replaced `@authenio/xml-encryption` with `xml-encryption` (latest version adds SHA-256/512 and OAEP support)
15
11
 
16
- - 🛠️ 修复加密断言逻辑,支持 `EncryptedAssertion` 字段提取
17
- 🛠️ Fixed encrypted assertion logic to handle `EncryptedAssertion` field
12
+ - 📦 CJS模块打包转为 ESModule
18
13
 
19
- - 📦 默认配置增加 `AttributeConsumingService` 和属性声明生成
20
- 📦 Added `AttributeConsumingService` to default elements and attribute value generation
14
+ - 将依赖包 `@authenio/xml-encryption` 替换为 `xml-encryption` 并升级版本对 sha256/512 加密密钥 OAEP 摘要方法的支持
21
15
 
22
- - 🗑️ 移除自定义函数模板,通过 `AttributeStatement` 配置多值属性
23
- 🗑️ Removed custom templates, added multi-value attribute support via `AttributeStatement`
16
+ - 🛠️ 修复加密断言验证签名函数 verifySignature 提取`Assertion` 字段的错误,增加对加密断言 `EncryptedAssertion` 字段提取逻辑
24
17
 
25
- - 🔒 签名算法升级为 SHA-256+,默认加密算法 AES_256_GCM
26
- 🔒 Upgraded signature algorithm to SHA-256+, default encryption to AES_256_GCM
18
+ - 📦 ServiceProvider实例化函数 attributeConsumingService字段参函数, 生成默认的 `AttributeConsumingService` 元素和属性值
27
19
 
28
- - 📦 CJS 模块打包转为 ESModule
29
- 📦 Migrated from CJS to ESModule packaging
20
+ - 🗑️ 移除作为Idp使用 IdentityProvider 函数自定义函数模板loginResponseTemplate字段的支持,并改进了自定义函数替换。
21
+ 改进createLoginResponse函数签名改为对象的传参方式
30
22
 
31
- - ⚙️ `createLoginResponse` 改为对象传参,新增 `AttributeStatement` 参数
32
- ⚙️ Refactored `createLoginResponse` to use object parameters with `AttributeStatement`
23
+ - 🔒 默认签名算法升级为 SHA-256,Idp默认加密算法为 AES_256_GCM
33
24
 
34
- - ⬆️ 升级依赖版本,移除 `node-rsa`/`node-forge`,改用原生 `crypto` 模块
35
- ⬆️ Upgraded dependencies, replaced `node-rsa`/`node-forge` with native `crypto`
25
+ - ⬆️ 升级所有能够升级的依赖版本,移除 `node-rsa`/`node-forge` 模块儿,改用原生nodejs `crypto` 模块实现。
36
26
 
37
- - 🌐 将 `url` 库替换为 `URL` 原生 API
38
- 🌐 Replaced `url` library with native `URL` API
27
+ - 🌐 将 `url` 库替换为 `URL` 原生 API
28
+ - 改进了如果响应为的绑定`urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect`,某些情况下未能DEFLATE压缩导致不能提取xml的异常情况的处理
29
+ - 现在如果遇到加密响应无需显示传递 `isAssertionEncrypted` 字段,也无需传递 `MessageSignatureOrder`
30
+ 字段。因为我认为是否加密应该是可以自动判断的,MessageSignatureOrder我修改了判断逻辑并在Keycloak 验证可以通过。使用前你应该自行验证这其中的风险
31
+ - 默认 elementsOrder 增加了 AttributeConsumingService 适配
32
+ - 我已经使用 Burp SAML Raider测试了 八种XSW都能良好的应对,以及XXE。你应该自行验证
39
33
 
40
34
  ---
41
35
 
42
36
  ## 欢迎 PR / Welcome PRs
37
+
43
38
  欢迎贡献代码或提供与其他框架集成的用例
44
39
  Welcome contributions or integration examples with frameworks
45
40
 
46
41
  ---
47
42
 
48
43
  ## 安装 / Installation
44
+ 宁应该在使用的前提下首先设置验证其
49
45
  ```js
50
- import * as samlify from 'samlify';
51
- import * as validator from '@authenio/samlify-xsd-schema-validator';
52
46
 
47
+ import * as validator from '@authenio/samlify-xsd-schema-validator';
48
+ import * as Saml from "samlesa";
49
+ import {Extractor,} from "samlesa";
50
+ import validator from '@authenio/samlify-node-xmllint'
53
51
  // 设置模式验证器 / Set schema validator
54
- samlify.setSchemaValidator(validator);
52
+ Saml.setSchemaValidator(validator);
53
+
54
+
55
+ ```
56
+
57
+ ## 生成密钥
58
+
59
+ 我们使用 openssl 生成密钥和证书用于测试。私钥可以使用密码保护,这是可选的。以下是生成私钥和自签名证书的命令。
60
+
61
+ > openssl genrsa -passout pass:foobar -out encryptKey.pem 4096
62
+ > openssl req -new -x509 -key encryptKey.pem -out encryptionCert.cer -days 3650
63
+
64
+ ## 当您作为IDP的伪代码使用示例
65
+
66
+ ```js
67
+ /** 本代码正对不同的绑定做出的方式伪代码*/
68
+ if (request.method === 'GET') {
69
+ data = request.query
70
+ bind = 'redirect'
71
+ infoQuery.query = request.query
72
+ let compressedResult = validateAndInflateSamlResponse(data.SAMLResponse)
73
+ console.log(compressedResult);
74
+ console.log("压缩结果---------------------")
75
+ infoQuery.octetString = buildOctetStringFromQuery(request.query)
76
+ dataResult = Extractor.extract(compressedResult.xml, loginResponseFields);
77
+ }
78
+ if (request.method === 'POST') {
79
+ data = request.body
80
+ bind = 'post'
81
+ infoQuery.body = request.body
82
+ dataResult = Extractor.extract(Base64.decode(decodeURIComponent(data.SAMLResponse)), loginResponseFields)
83
+ }
84
+ /** 宁应该自行实施根据响应提取出来的Issur去数据库查找元数据*/
85
+ // 1. 提取SAML发行者信息
86
+ if (!dataResult.issuer) {
87
+ return reply.view('errorHtml.html', {
88
+ errorMessage: `无效的发行者`, errorCode: StatusCode?.Responder, requestId: ""
89
+ })
90
+ }
91
+
92
+ let result = await samlCollection.findOne({issuer:dataResult.issuer});
93
+ const idp = new Saml.IdentityProvider({
94
+ metadata: result.metadata,
95
+ });
96
+
97
+ /** 检查断言*/
98
+ let extract = null
99
+ /** 先看数据库有没有*/
100
+ let bindType = 'post' //redirect post ......您应该自定判断
101
+ let parseResult = await sp.parseLoginResponse(idp, bindType, infoQuery)
102
+
103
+ /**如果解析成功 你应该去验证元素结果中的 attribute 和 Audience issur是否是你期待的 inResponseTo检查 是否有必须的属性没有 都需要您进行严密的的考察 */
104
+
105
+ if(upaboveFieldCheckAllSuccess){
106
+ return repla.view('success.ejs',{...your template data})
107
+ }
108
+ /*success.ejs template example */
109
+ /**/
110
+ <!-- 隐藏的 SAML 表单 -->
111
+ /*
112
+ <form id="saml-form" method="post" action="<%= entityEndpoint %>" style="display: none;">
113
+ <input type="hidden" name="<%= type %>" value="<%= context %>" />
114
+ <input type="hidden" name="RelayState" value="<%= relayState %>" />
115
+ </form>
116
+
117
+ <script>
118
+ // 延迟 1.5 秒提交以展示加载效果
119
+
120
+ document.getElementById('saml-form').submit();
121
+
122
+ // 兼容性处理:若 5 秒后仍未跳转显示提示
123
+ setTimeout(() => {
124
+ document.querySelector('.loading-subtext').textContent =
125
+ '跳转时间较长,请检查网络或联系系统管理员';
126
+ }, 1500);
127
+ </script>*/
128
+
55
129
  ```
package/build/index.js CHANGED
@@ -16,4 +16,3 @@ export { Constants, Extractor,
16
16
  IdentityProvider, IdentityProviderInstance, ServiceProvider, ServiceProviderInstance,
17
17
  // set context
18
18
  setSchemaValidator, setDOMParserOptions };
19
- //# sourceMappingURL=index.js.map
package/build/src/api.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { DOMParser as dom } from '@xmldom/xmldom';
2
+ import { validate as defaultValidator } from "./schemaValidator.js";
2
3
  const context = {
3
- validate: undefined,
4
+ validate: defaultValidator,
4
5
  dom: new dom()
5
6
  };
6
7
  export function getContext() {
@@ -16,4 +17,3 @@ export function setSchemaValidator(params) {
16
17
  export function setDOMParserOptions(options = {}) {
17
18
  context.dom = new dom(options);
18
19
  }
19
- //# sourceMappingURL=api.js.map
@@ -335,4 +335,3 @@ const postBinding = {
335
335
  base64LogoutResponse,
336
336
  };
337
337
  export default postBinding;
338
- //# sourceMappingURL=binding-post.js.map
@@ -310,4 +310,3 @@ const redirectBinding = {
310
310
  logoutResponseRedirectURL,
311
311
  };
312
312
  export default redirectBinding;
313
- //# sourceMappingURL=binding-redirect.js.map
@@ -199,4 +199,3 @@ const simpleSignBinding = {
199
199
  base64LoginResponse,
200
200
  };
201
201
  export default simpleSignBinding;
202
- //# sourceMappingURL=binding-simplesign.js.map
@@ -91,4 +91,3 @@ export class IdentityProvider extends Entity {
91
91
  });
92
92
  }
93
93
  }
94
- //# sourceMappingURL=entity-idp.js.map
@@ -86,4 +86,3 @@ export class ServiceProvider extends Entity {
86
86
  });
87
87
  }
88
88
  }
89
- //# sourceMappingURL=entity-sp.js.map
@@ -191,4 +191,3 @@ export default class Entity {
191
191
  });
192
192
  }
193
193
  }
194
- //# sourceMappingURL=entity.js.map
@@ -359,4 +359,3 @@ export function extract(context, fields) {
359
359
  return result;
360
360
  }, {});
361
361
  }
362
- //# sourceMappingURL=extractor.js.map
package/build/src/flow.js CHANGED
@@ -371,4 +371,3 @@ export function flow(options) {
371
371
  }
372
372
  return Promise.reject('ERR_UNEXPECTED_FLOW');
373
373
  }
374
- //# sourceMappingURL=flow.js.map
@@ -311,79 +311,6 @@ const libSaml = () => {
311
311
  }
312
312
  return isBase64Output !== false ? utility.base64Encode(sig.getSignedXml()) : sig.getSignedXml();
313
313
  },
314
- checkSamlSignatureOrder(samlResponseXml) {
315
- const { dom } = getContext();
316
- const doc = dom.parseFromString(samlResponseXml, 'application/xml');
317
- // 获取 Response 根节点
318
- const response = doc.documentElement;
319
- if (!response || response.localName !== "Response") {
320
- throw new Error("Invalid SAML Response");
321
- }
322
- // 获取 Response 的 ID
323
- const responseId = response.getAttribute("ID");
324
- // 查找 Response 下的直接子节点
325
- const children = Array.from(response.childNodes).filter((node) => node.nodeType === 1); // 过滤非元素节点
326
- // 1. 查找签名块 (可能带不同前缀: ds: 或 dsig:)
327
- const signature = children.find((node) => {
328
- // @ts-ignore
329
- const localName = node.nodeName;
330
- console.log("这就是名字1");
331
- console.log(localName);
332
- // @ts-ignore
333
- const ns = node.namespaceURI;
334
- return ((localName.includes("Signature") && ns === "http://www.w3.org/2000/09/xmldsig#")
335
- || node.nodeName.includes("Signature"));
336
- });
337
- if (!signature) {
338
- throw new Error("SAML Response is not signed");
339
- }
340
- // @ts-ignore
341
- // 2. 检查签名的 Reference URI
342
- // @ts-ignore
343
- console.log(signature.getElementsByTagName("Reference"));
344
- console.log("找到了神恶魔---------------");
345
- // @ts-ignore
346
- const reference = Array.from(signature.getElementsByTagName("Reference")).find((ref) => {
347
- // @ts-ignore
348
- console.log(ref?.parentNode?.localName);
349
- console.log("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
350
- // @ts-ignore
351
- return ref?.parentNode?.localName?.includes("SignedInfo");
352
- });
353
- console.log(reference);
354
- console.log("给我看一下-----------------");
355
- // @ts-ignore
356
- const referenceUri = reference?.getAttribute("URI") || "";
357
- console.log("1他妈的-------------------");
358
- console.log(referenceUri);
359
- console.log(`#${responseId}`);
360
- console.log("他妈的-------------------");
361
- // 是否对整个 Response 签名
362
- const isSignWholeResponse = referenceUri === `#${responseId}`;
363
- // 3. 查找 EncryptedAssertion
364
- const encryptedAssertion = children.find((node) => {
365
- // @ts-ignore
366
- const localName = node?.localName;
367
- return ((localName === "EncryptedAssertion")
368
- || node.nodeName.includes("EncryptedAssertion"));
369
- });
370
- if (!encryptedAssertion) {
371
- throw new Error("EncryptedAssertion not found");
372
- }
373
- // 4. 比较签名和加密断言的位置索引
374
- const signatureIndex = children.indexOf(signature);
375
- const encryptedIndex = children.indexOf(encryptedAssertion);
376
- console.log(signatureIndex);
377
- console.log(encryptedIndex);
378
- console.log("66666666666666666");
379
- // 判断逻辑
380
- if (isSignWholeResponse && encryptedIndex > signatureIndex) {
381
- return "encrypt-then-sign"; // 先加密后签名
382
- }
383
- else {
384
- return "sign-then-encrypt"; // 先签名后加密
385
- }
386
- },
387
314
  /**
388
315
  * @desc Verify the XML signature
389
316
  * @param {string} xml xml
@@ -767,4 +694,3 @@ const libSaml = () => {
767
694
  };
768
695
  };
769
696
  export default libSaml();
770
- //# sourceMappingURL=libsaml.js.map
@@ -131,4 +131,3 @@ export class IdpMetadata extends Metadata {
131
131
  return this.meta.singleSignOnService;
132
132
  }
133
133
  }
134
- //# sourceMappingURL=metadata-idp.js.map
@@ -237,4 +237,3 @@ export class SpMetadata extends Metadata {
237
237
  return this.meta.assertionConsumerService;
238
238
  }
239
239
  }
240
- //# sourceMappingURL=metadata-sp.js.map
@@ -136,4 +136,3 @@ export default class Metadata {
136
136
  return supportBindings;
137
137
  }
138
138
  }
139
- //# sourceMappingURL=metadata.js.map