samlesa 3.2.1 → 3.3.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.
@@ -3,6 +3,8 @@ import { uniq, last, zipObject, notEmpty } from './utility.js';
3
3
  import { getContext } from './api.js';
4
4
  import camelCase from 'camelcase';
5
5
  function buildAbsoluteXPath(paths) {
6
+ if (!paths || paths.length === 0)
7
+ return '';
6
8
  return paths.reduce((currentPath, name) => {
7
9
  let appendedPath = currentPath;
8
10
  const isWildcard = name.startsWith('~');
@@ -10,14 +12,14 @@ function buildAbsoluteXPath(paths) {
10
12
  const pathName = name.replace('~', '');
11
13
  appendedPath = currentPath + `/*[contains(local-name(), '${pathName}')]`;
12
14
  }
13
- if (!isWildcard) {
15
+ else {
14
16
  appendedPath = currentPath + `/*[local-name(.)='${name}']`;
15
17
  }
16
18
  return appendedPath;
17
19
  }, '');
18
20
  }
19
21
  function buildAttributeXPath(attributes) {
20
- if (attributes.length === 0) {
22
+ if (!attributes || attributes.length === 0) {
21
23
  return '/text()';
22
24
  }
23
25
  if (attributes.length === 1) {
@@ -26,355 +28,359 @@ function buildAttributeXPath(attributes) {
26
28
  const filters = attributes.map(attribute => `name()='${attribute}'`).join(' or ');
27
29
  return `/@*[${filters}]`;
28
30
  }
31
+ // ... (其他字段配置如 loginRequestFields 等保持不变,为节省篇幅此处省略,请保留你原有的所有 fields 定义) ...
32
+ // 为了完整性,这里假设你保留了之前所有的 fields 定义 (loginRequestFields, idpMetadataFields 等)
33
+ // 重点修正下方的 spMetadataFields 和 extract 函数
29
34
  export const loginRequestFields = [
30
- {
31
- key: 'request',
32
- localPath: ['AuthnRequest'],
33
- attributes: ['ID', 'IssueInstant', 'Destination', 'AssertionConsumerServiceURL', 'ProtocolBinding', 'ForceAuthn', 'IsPassive', 'AssertionConsumerServiceIndex', 'AttributeConsumingServiceIndex']
34
- },
35
- {
36
- key: 'issuer',
37
- localPath: ['AuthnRequest', 'Issuer'],
38
- attributes: []
39
- },
40
- {
41
- key: 'nameIDPolicy',
42
- localPath: ['AuthnRequest', 'NameIDPolicy'],
43
- attributes: ['Format', 'AllowCreate']
44
- },
45
- {
46
- key: 'authnContextClassRef',
47
- localPath: ['AuthnRequest', 'AuthnContextClassRef'],
48
- attributes: []
49
- },
50
- {
51
- key: 'signature',
52
- localPath: ['AuthnRequest', 'Signature'],
53
- attributes: [],
54
- context: true
55
- }
35
+ { key: 'request', localPath: ['AuthnRequest'], attributes: ['ID', 'IssueInstant', 'Destination', 'AssertionConsumerServiceURL', 'ProtocolBinding', 'ForceAuthn', 'IsPassive', 'AssertionConsumerServiceIndex', 'AttributeConsumingServiceIndex'] },
36
+ { key: 'issuer', localPath: ['AuthnRequest', 'Issuer'], attributes: [] },
37
+ { key: 'nameIDPolicy', localPath: ['AuthnRequest', 'NameIDPolicy'], attributes: ['Format', 'AllowCreate'] },
38
+ { key: 'authnContextClassRef', localPath: ['AuthnRequest', 'AuthnContextClassRef'], attributes: [] },
39
+ { key: 'signature', localPath: ['AuthnRequest', 'Signature'], attributes: [], context: true }
56
40
  ];
57
41
  export const artifactResolveFields = [
58
- {
59
- key: 'request',
60
- localPath: ['ArtifactResolve'],
61
- attributes: ['ID', 'IssueInstant', 'Version']
62
- },
63
- {
64
- key: 'issuer', localPath: ['ArtifactResolve', 'Issuer'], attributes: []
65
- },
66
- {
67
- key: 'Artifact', localPath: ['ArtifactResolve', 'Artifact'], attributes: []
68
- },
69
- {
70
- key: 'signature', localPath: ['ArtifactResolve', 'Signature'], attributes: [], context: true
71
- },
42
+ { key: 'request', localPath: ['ArtifactResolve'], attributes: ['ID', 'IssueInstant', 'Version'] },
43
+ { key: 'issuer', localPath: ['ArtifactResolve', 'Issuer'], attributes: [] },
44
+ { key: 'Artifact', localPath: ['ArtifactResolve', 'Artifact'], attributes: [] },
45
+ { key: 'signature', localPath: ['ArtifactResolve', 'Signature'], attributes: [], context: true },
72
46
  ];
73
47
  export const artifactResponseFields = [
74
- {
75
- key: 'request',
76
- localPath: ['Envelope', 'Body', 'ArtifactResolve'],
77
- attributes: ['ID', 'IssueInstant', 'Version']
78
- },
79
- {
80
- key: 'issuer', localPath: ['Envelope', 'Body', 'ArtifactResolve', 'Issuer'], attributes: []
81
- },
82
- {
83
- key: 'Artifact', localPath: ['Envelope', 'Body', 'ArtifactResolve', 'Artifact'], attributes: []
84
- },
85
- {
86
- key: 'signature', localPath: ['Envelope', 'Body', 'ArtifactResolve', 'Signature'], attributes: [], context: true
87
- },
48
+ { key: 'request', localPath: ['Envelope', 'Body', 'ArtifactResolve'], attributes: ['ID', 'IssueInstant', 'Version'] },
49
+ { key: 'issuer', localPath: ['Envelope', 'Body', 'ArtifactResolve', 'Issuer'], attributes: [] },
50
+ { key: 'Artifact', localPath: ['Envelope', 'Body', 'ArtifactResolve', 'Artifact'], attributes: [] },
51
+ { key: 'signature', localPath: ['Envelope', 'Body', 'ArtifactResolve', 'Signature'], attributes: [], context: true },
88
52
  ];
89
- // support two-tiers status code
90
53
  export const loginResponseStatusFields = [
91
- {
92
- key: 'top',
93
- localPath: ['Response', 'Status', 'StatusCode'],
94
- attributes: ['Value'],
95
- },
96
- {
97
- key: 'second',
98
- localPath: ['Response', 'Status', 'StatusCode', 'StatusCode'],
99
- attributes: ['Value'],
100
- }
54
+ { key: 'top', localPath: ['Response', 'Status', 'StatusCode'], attributes: ['Value'] },
55
+ { key: 'second', localPath: ['Response', 'Status', 'StatusCode', 'StatusCode'], attributes: ['Value'] }
101
56
  ];
102
- // support two-tiers status code
103
57
  export const loginArtifactResponseStatusFields = [
104
- {
105
- key: 'top',
106
- localPath: ['Envelope', 'Body', 'ArtifactResponse', 'Status', 'StatusCode'],
107
- attributes: ['Value'],
108
- },
109
- {
110
- key: 'second',
111
- localPath: ['Envelope', 'Body', 'ArtifactResponse', 'Status', 'StatusCode', 'StatusCode'],
112
- attributes: ['Value'],
113
- }
58
+ { key: 'top', localPath: ['Envelope', 'Body', 'ArtifactResponse', 'Status', 'StatusCode'], attributes: ['Value'] },
59
+ { key: 'second', localPath: ['Envelope', 'Body', 'ArtifactResponse', 'Status', 'StatusCode', 'StatusCode'], attributes: ['Value'] }
114
60
  ];
115
- // support two-tiers status code
116
61
  export const logoutResponseStatusFields = [
117
- {
118
- key: 'top',
119
- localPath: ['LogoutResponse', 'Status', 'StatusCode'],
120
- attributes: ['Value']
121
- },
122
- {
123
- key: 'second',
124
- localPath: ['LogoutResponse', 'Status', 'StatusCode', 'StatusCode'],
125
- attributes: ['Value'],
126
- }
62
+ { key: 'top', localPath: ['LogoutResponse', 'Status', 'StatusCode'], attributes: ['Value'] },
63
+ { key: 'second', localPath: ['LogoutResponse', 'Status', 'StatusCode', 'StatusCode'], attributes: ['Value'] }
127
64
  ];
128
65
  export const loginResponseFields = assertion => [
129
- {
130
- key: 'conditions',
131
- localPath: ['Assertion', 'Conditions'],
132
- attributes: ['NotBefore', 'NotOnOrAfter'],
133
- shortcut: assertion
66
+ { key: 'conditions', localPath: ['Assertion', 'Conditions'], attributes: ['NotBefore', 'NotOnOrAfter'], shortcut: assertion },
67
+ { key: 'response', localPath: ['Response'], attributes: ['ID', 'IssueInstant', 'Destination', 'InResponseTo', 'Version'] },
68
+ { key: 'audience', localPath: ['Assertion', 'Conditions', 'AudienceRestriction', 'Audience'], attributes: [], shortcut: assertion },
69
+ { key: 'issuer', localPath: ['Assertion', 'Issuer'], attributes: [], shortcut: assertion },
70
+ { key: 'nameID', localPath: ['Assertion', 'Subject', 'NameID'], attributes: [], shortcut: assertion },
71
+ { key: 'sessionIndex', localPath: ['Assertion', 'AuthnStatement'], attributes: ['AuthnInstant', 'SessionNotOnOrAfter', 'SessionIndex'], shortcut: assertion },
72
+ { key: 'attributes', localPath: ['Assertion', 'AttributeStatement', 'Attribute'], index: ['Name'], attributePath: ['AttributeValue'], attributes: [], shortcut: assertion },
73
+ { key: 'subjectConfirmation', localPath: ['Assertion', 'Subject', 'SubjectConfirmation', 'SubjectConfirmationData'], attributes: ['Recipient', 'InResponseTo', 'NotOnOrAfter'], shortcut: assertion },
74
+ { key: 'oneTimeUse', localPath: ['Assertion', 'Conditions', 'OneTimeUse'], attributes: [], shortcut: assertion },
75
+ { key: 'status', localPath: ['Response', 'Status', 'StatusCode'], attributes: ['Value'] },
76
+ ];
77
+ export const logoutRequestFields = [
78
+ { key: 'request', localPath: ['LogoutRequest'], attributes: ['ID', 'IssueInstant', 'Destination'] },
79
+ { key: 'issuer', localPath: ['LogoutRequest', 'Issuer'], attributes: [] },
80
+ { key: 'nameID', localPath: ['LogoutRequest', 'NameID'], attributes: [] },
81
+ { key: 'sessionIndex', localPath: ['LogoutRequest', 'SessionIndex'], attributes: [] },
82
+ { key: 'signature', localPath: ['LogoutRequest', 'Signature'], attributes: [], context: true }
83
+ ];
84
+ export const logoutResponseFields = [
85
+ { key: 'response', localPath: ['LogoutResponse'], attributes: ['ID', 'Destination', 'InResponseTo'] },
86
+ { key: 'issuer', localPath: ['LogoutResponse', 'Issuer'], attributes: [] },
87
+ { key: 'signature', localPath: ['LogoutResponse', 'Signature'], attributes: [], context: true }
88
+ ];
89
+ // ============================================================================
90
+ // 增强版:IdP 元数据提取字段配置
91
+ // ============================================================================
92
+ export const idpMetadataFields = [
93
+ // --- 1. 基础标识 ---
94
+ {
95
+ key: 'entityID',
96
+ localPath: ['EntityDescriptor'],
97
+ attributes: ['entityID']
134
98
  },
135
99
  {
136
- key: 'response',
137
- localPath: ['Response'],
138
- attributes: ['ID', 'IssueInstant', 'Destination', 'InResponseTo', 'Version'],
100
+ // 可选:提取整个 EntityDescriptor 的 validUntil 和 cacheDuration
101
+ key: 'entityDescriptor',
102
+ localPath: ['EntityDescriptor'],
103
+ attributes: ['validUntil', 'cacheDuration']
139
104
  },
140
- {
141
- key: 'audience',
142
- localPath: ['Assertion', 'Conditions', 'AudienceRestriction', 'Audience'],
143
- attributes: [],
144
- shortcut: assertion
105
+ // --- 2. IDPSSODescriptor 核心属性 ---
106
+ {
107
+ key: 'idpSSODescriptor',
108
+ localPath: ['EntityDescriptor', 'IDPSSODescriptor'],
109
+ attributes: [
110
+ 'protocolSupportEnumeration',
111
+ 'WantAuthnRequestsSigned', // IdP 是否希望 SP 对请求签名
112
+ 'cacheDuration'
113
+ ]
145
114
  },
146
- // {
147
- // key: 'issuer',
148
- // localPath: ['Response', 'Issuer'],
149
- // attributes: []
150
- // },
115
+ // --- 3. 服务端点列表 (Endpoints) ---
151
116
  {
152
- key: 'issuer',
153
- localPath: ['Assertion', 'Issuer'],
154
- attributes: [],
155
- shortcut: assertion
117
+ // 单点登录服务 (SSO) - 核心
118
+ key: 'singleSignOnService',
119
+ localPath: ['EntityDescriptor', 'IDPSSODescriptor', 'SingleSignOnService'],
120
+ attributes: ['Binding', 'Location', 'ResponseLocation'], // ResponseLocation 用于某些绑定
121
+ listMode: true
156
122
  },
157
123
  {
158
- key: 'nameID',
159
- localPath: ['Assertion', 'Subject', 'NameID'],
160
- attributes: [],
161
- shortcut: assertion
124
+ // 单点注销服务 (SLO)
125
+ key: 'singleLogoutService',
126
+ localPath: ['EntityDescriptor', 'IDPSSODescriptor', 'SingleLogoutService'],
127
+ attributes: ['Binding', 'Location'],
128
+ listMode: true
162
129
  },
163
130
  {
164
- key: 'sessionIndex',
165
- localPath: ['Assertion', 'AuthnStatement'],
166
- attributes: ['AuthnInstant', 'SessionNotOnOrAfter', 'SessionIndex'],
167
- shortcut: assertion
131
+ // Artifact 解析服务 (如果使用 Artifact 绑定)
132
+ key: 'artifactResolutionService',
133
+ localPath: ['EntityDescriptor', 'IDPSSODescriptor', 'ArtifactResolutionService'],
134
+ attributes: ['Binding', 'Location', 'index', 'isDefault'],
135
+ listMode: true
168
136
  },
169
137
  {
170
- key: 'attributes',
171
- localPath: ['Assertion', 'AttributeStatement', 'Attribute'],
172
- index: ['Name'],
173
- attributePath: ['AttributeValue'],
174
- attributes: [],
175
- shortcut: assertion
138
+ // ManageNameID 服务
139
+ key: 'manageNameIDService',
140
+ localPath: ['EntityDescriptor', 'IDPSSODescriptor', 'ManageNameIDService'],
141
+ attributes: ['Binding', 'Location'],
142
+ listMode: true
176
143
  },
144
+ // --- 4. 名称 ID 格式 (NameID Formats) ---
177
145
  {
178
- key: 'subjectConfirmation',
179
- localPath: ['Assertion', 'Subject', 'SubjectConfirmation', 'SubjectConfirmationData'],
180
- attributes: ['Recipient', 'InResponseTo', 'NotOnOrAfter'],
181
- shortcut: assertion
146
+ // 提取所有支持的 NameID 格式 (文本内容)
147
+ key: 'nameIDFormat',
148
+ localPath: ['EntityDescriptor', 'IDPSSODescriptor', 'NameIDFormat'],
149
+ attributes: []
150
+ // 注意:如果 extract 函数未完全支持 text() 的 listMode,这里可能只返回第一个。
151
+ // 如果需要数组,需确保 extract 逻辑完善,或者此处暂时只取主要的一个。
182
152
  },
183
153
  {
184
- key: 'oneTimeUse',
185
- localPath: ['Assertion', 'Conditions', 'OneTimeUse'],
186
- attributes: [],
187
- shortcut: assertion
154
+ // 获取主要的 NameID Policy 格式 (如果有显式声明)
155
+ key: 'nameIDPolicyFormat',
156
+ localPath: ['EntityDescriptor', 'IDPSSODescriptor', 'NameIDPolicy'],
157
+ attributes: ['Format']
188
158
  },
159
+ // --- 5. 组织信息 (Organization) ---
189
160
  {
190
- key: 'status',
191
- localPath: ['Response', 'Status', 'StatusCode'],
192
- attributes: ['Value']
161
+ key: 'organizationName',
162
+ localPath: ['EntityDescriptor', 'Organization', 'OrganizationName'],
163
+ attributes: [] // 取文本内容
193
164
  },
194
- ];
195
- export const logoutRequestFields = [
196
165
  {
197
- key: 'request',
198
- localPath: ['LogoutRequest'],
199
- attributes: ['ID', 'IssueInstant', 'Destination']
166
+ key: 'organizationDisplayName',
167
+ localPath: ['EntityDescriptor', 'Organization', 'OrganizationDisplayName'],
168
+ attributes: []
200
169
  },
201
170
  {
202
- key: 'issuer',
203
- localPath: ['LogoutRequest', 'Issuer'],
171
+ key: 'organizationURL',
172
+ localPath: ['EntityDescriptor', 'Organization', 'OrganizationURL'],
204
173
  attributes: []
205
174
  },
175
+ // --- 6. 联系人信息 (ContactPerson) ---
206
176
  {
207
- key: 'nameID',
208
- localPath: ['LogoutRequest', 'NameID'],
209
- attributes: []
177
+ key: 'contactPerson',
178
+ localPath: ['EntityDescriptor', 'ContactPerson'],
179
+ attributes: ['contactType'],
180
+ listMode: true
181
+ // 局限:目前只能提取 contactType。如需提取 Email/GivenName,需扩展 extract 逻辑。
210
182
  },
183
+ // --- 7. 证书与密钥信息 (Certificates & Keys) ---
184
+ // 这些 key 会触发 extract 函数内部的硬编码逻辑,自动查找对应 @use 的证书
185
+ // 7.1 签名证书 (IdP 用来签名响应/断言)
211
186
  {
212
- key: 'sessionIndex',
213
- localPath: ['LogoutRequest', 'SessionIndex'],
214
- attributes: []
187
+ key: 'signingCert'
188
+ // localPath attributes 将被内部逻辑忽略
215
189
  },
190
+ // 7.2 加密证书 (IdP 用来加密断言中的敏感信息,如果有)
216
191
  {
217
- key: 'signature',
218
- localPath: ['LogoutRequest', 'Signature'],
219
- attributes: [],
220
- context: true
221
- }
222
- ];
223
- export const logoutResponseFields = [
192
+ key: 'encryptCert'
193
+ },
194
+ // 7.3 签名密钥名称 (KeyName)
224
195
  {
225
- key: 'response',
226
- localPath: ['LogoutResponse'],
227
- attributes: ['ID', 'Destination', 'InResponseTo']
196
+ key: 'signingKeyName'
228
197
  },
198
+ // 7.4 加密密钥名称 (KeyName)
229
199
  {
230
- key: 'issuer',
231
- localPath: ['LogoutResponse', 'Issuer'],
232
- attributes: []
200
+ key: 'encryptionKeyName'
233
201
  },
202
+ // --- 8. 其他扩展属性 (可选) ---
234
203
  {
235
- key: 'signature',
236
- localPath: ['LogoutResponse', 'Signature'],
237
- attributes: [],
238
- context: true
204
+ // 提取 AttributeConsumingService (如果 IdP 声明了它需要的属性)
205
+ key: 'attributeConsumingService',
206
+ localPath: ['EntityDescriptor', 'IDPSSODescriptor', 'AttributeConsumingService'],
207
+ attributes: ['index', 'isDefault'],
208
+ listMode: true
239
209
  }
240
210
  ];
211
+ // ============================================================================
212
+ // 修正后的 SP 元数据提取字段配置
213
+ // ============================================================================
214
+ export const spMetadataFields = [
215
+ { key: 'entityID', localPath: ['EntityDescriptor'], attributes: ['entityID'] },
216
+ { key: 'spSSODescriptor', localPath: ['EntityDescriptor', 'SPSSODescriptor'], attributes: ['protocolSupportEnumeration', 'AuthnRequestsSigned', 'WantAssertionsSigned'] },
217
+ { key: 'assertionConsumerService', localPath: ['EntityDescriptor', 'SPSSODescriptor', 'AssertionConsumerService'], attributes: ['Binding', 'Location', 'index', 'isDefault'], listMode: true },
218
+ { key: 'singleLogoutService', localPath: ['EntityDescriptor', 'SPSSODescriptor', 'SingleLogoutService'], attributes: ['Binding', 'Location'], listMode: true },
219
+ { key: 'artifactResolutionService', localPath: ['EntityDescriptor', 'SPSSODescriptor', 'ArtifactResolutionService'], attributes: ['Binding', 'Location', 'index', 'isDefault'], listMode: true },
220
+ { key: 'manageNameIDService', localPath: ['EntityDescriptor', 'SPSSODescriptor', 'ManageNameIDService'], attributes: ['Binding', 'Location'], listMode: true },
221
+ { key: 'nameIDFormat', localPath: ['EntityDescriptor', 'SPSSODescriptor', 'NameIDFormat'], attributes: [] },
222
+ { key: 'organizationName', localPath: ['EntityDescriptor', 'Organization', 'OrganizationName'], attributes: [] },
223
+ { key: 'organizationDisplayName', localPath: ['EntityDescriptor', 'Organization', 'OrganizationDisplayName'], attributes: [] },
224
+ { key: 'organizationURL', localPath: ['EntityDescriptor', 'Organization', 'OrganizationURL'], attributes: [] },
225
+ { key: 'contactPerson', localPath: ['EntityDescriptor', 'ContactPerson'], attributes: ['contactType'], listMode: true },
226
+ // 特殊字段:触发 extract 内部的硬编码逻辑
227
+ // localPath 和 attributes 在这里不起作用,仅作为占位符
228
+ { key: 'signingCert' },
229
+ { key: 'encryptCert' },
230
+ { key: 'signingKeyName' },
231
+ { key: 'encryptionKeyName' }
232
+ ];
241
233
  export function extract(context, fields) {
242
234
  const { dom } = getContext();
243
235
  const rootDoc = dom.parseFromString(context, 'application/xml');
244
236
  return fields.reduce((result, field) => {
245
- // get essential fields
246
237
  const key = field.key;
247
- const localPath = field.localPath;
248
- const attributes = field.attributes;
238
+ // 安全解构,防止 undefined
239
+ const localPath = field.localPath || [];
240
+ const attributes = field.attributes || [];
249
241
  const isEntire = field.context;
250
242
  const shortcut = field.shortcut;
251
- // get optional fields
252
243
  const index = field.index;
253
244
  const attributePath = field.attributePath;
254
- // set allowing overriding if there is a shortcut injected
245
+ const listMode = field.listMode;
255
246
  let targetDoc = rootDoc;
256
- // if shortcut is used, then replace the doc
257
- // it's a design for overriding the doc used during runtime
258
247
  if (shortcut) {
259
248
  targetDoc = dom.parseFromString(shortcut, 'application/xml');
260
249
  }
261
- // special case: multiple path
262
- /*
263
- {
264
- key: 'issuer',
265
- localPath: [
266
- ['Response', 'Issuer'],
267
- ['Response', 'Assertion', 'Issuer']
268
- ],
269
- attributes: []
270
- }
271
- */
272
- if (localPath.every(path => Array.isArray(path))) {
273
- const multiXPaths = localPath
274
- .map(path => {
275
- // not support attribute yet, so ignore it
276
- return `${buildAbsoluteXPath(path)}/text()`;
277
- })
278
- .join(' | ');
250
+ // ==========================================================================
251
+ // 【核心修复】特殊处理:证书和 KeyName 提取 (Hardcoded logic)
252
+ // 不再硬编码 IDPSSODescriptor 或 SPSSODescriptor,而是全局搜索 @use 属性
253
+ // ==========================================================================
254
+ if (key === 'signingCert' || key === 'encryptCert' || key === 'signingKeyName' || key === 'encryptionKeyName') {
255
+ const isSigning = key.startsWith('signing');
256
+ const useType = isSigning ? 'signing' : 'encryption';
257
+ const isKeyName = key.endsWith('KeyName');
258
+ // 通用 XPath:查找任意层级下符合 @use 条件的 KeyDescriptor
259
+ const kdXPath = `//*[local-name(.)='KeyDescriptor' and @use='${useType}']`;
260
+ let fullXPath = '';
261
+ if (isKeyName) {
262
+ // 提取 KeyName 文本
263
+ fullXPath = `${kdXPath}/*[local-name(.)='KeyInfo']/*[local-name(.)='KeyName']/text()`;
264
+ }
265
+ else {
266
+ // 提取 X509Certificate 文本
267
+ fullXPath = `${kdXPath}/*[local-name(.)='KeyInfo']/*[local-name(.)='X509Data']/*[local-name(.)='X509Certificate']/text()`;
268
+ }
269
+ try {
270
+ // @ts-ignore
271
+ const nodes = select(fullXPath, targetDoc);
272
+ if (isKeyName) {
273
+ const keyNames = nodes.map((n) => n.nodeValue).filter(notEmpty);
274
+ return {
275
+ ...result,
276
+ [key]: keyNames.length > 0 ? keyNames[0] : null
277
+ };
278
+ }
279
+ else {
280
+ const certs = nodes.map((n) => {
281
+ const val = n.nodeValue || n.value;
282
+ return val ? val.replace(/\r\n|\r|\n/g, '') : null;
283
+ }).filter(notEmpty);
284
+ return {
285
+ ...result,
286
+ [key]: certs.length > 0 ? certs[0] : null
287
+ };
288
+ }
289
+ }
290
+ catch (e) {
291
+ console.error(`Error extracting ${key}:`, e);
292
+ return { ...result, [key]: null };
293
+ }
294
+ }
295
+ // 特殊 case: 多路径 (原有逻辑)
296
+ if (Array.isArray(localPath) && localPath.length > 0 && Array.isArray(localPath[0])) {
297
+ const multiXPaths = localPath.map(path => `${buildAbsoluteXPath(path)}/text()`).join(' | ');
298
+ // @ts-ignore
299
+ const nodes = select(multiXPaths, targetDoc);
300
+ return {
301
+ ...result,
302
+ [key]: uniq(nodes.map((n) => n.nodeValue).filter(notEmpty))
303
+ };
304
+ }
305
+ // 此时 localPath 必然是 string[]
306
+ const currentLocalPath = localPath;
307
+ // 如果 localPath 为空数组(如特殊字段未定义 path),且未命中上面的特殊逻辑,则跳过
308
+ if (currentLocalPath.length === 0 && !isEntire) {
309
+ // 对于没有 path 且不是特殊处理的字段,返回 null 或跳过
310
+ return { ...result, [key]: null };
311
+ }
312
+ const baseXPath = buildAbsoluteXPath(currentLocalPath);
313
+ // --- 新增:列表模式处理 (用于 SSO Service, ACS 等) ---
314
+ if (listMode && attributes.length > 0) {
315
+ // @ts-ignore
316
+ const nodes = select(baseXPath, targetDoc);
317
+ const resultList = nodes.map((node) => {
318
+ const attrResult = {};
319
+ attributes.forEach(attr => {
320
+ if (node.getAttribute) {
321
+ const val = node.getAttribute(attr);
322
+ if (val) {
323
+ attrResult[camelCase(attr, { locale: 'en-us' })] = val;
324
+ }
325
+ }
326
+ });
327
+ return attrResult;
328
+ });
279
329
  return {
280
330
  ...result,
281
- // @ts-expect-error misssing Node properties are not needed
282
- [key]: uniq(select(multiXPaths, targetDoc).map((n) => n.nodeValue).filter(notEmpty))
331
+ [key]: resultList
283
332
  };
284
333
  }
285
- // eo special case: multiple path
286
- const baseXPath = buildAbsoluteXPath(localPath);
287
334
  const attributeXPath = buildAttributeXPath(attributes);
288
- // special case: get attributes where some are in child, some are in parent
289
- /*
290
- {
291
- key: 'attributes',
292
- localPath: ['Response', 'Assertion', 'AttributeStatement', 'Attribute'],
293
- index: ['Name'],
294
- attributePath: ['AttributeValue'],
295
- attributes: []
296
- }
297
- */
335
+ // 特殊 case: 属性聚合 (原有逻辑 - Attributes with index)
298
336
  if (index && attributePath) {
299
- // find the index in localpath
300
337
  const indexPath = buildAttributeXPath(index);
301
338
  const fullLocalXPath = `${baseXPath}${indexPath}`;
302
- // @ts-expect-error misssing Node properties are not needed
339
+ // @ts-ignore
303
340
  const parentNodes = select(baseXPath, targetDoc);
304
- // [uid, mail, edupersonaffiliation], ready for aggregate
305
- // @ts-expect-error misssing Node properties are not needed
341
+ // @ts-ignore
306
342
  const parentAttributes = select(fullLocalXPath, targetDoc).map((n) => n.value);
307
- // [attribute, attributevalue]
308
- const childXPath = buildAbsoluteXPath([last(localPath)].concat(attributePath));
343
+ const childXPath = buildAbsoluteXPath([last(currentLocalPath)].concat(attributePath));
309
344
  const childAttributeXPath = buildAttributeXPath(attributes);
310
345
  const fullChildXPath = `${childXPath}${childAttributeXPath}`;
311
- // [ 'test', 'test@example.com', [ 'users', 'examplerole1' ] ]
312
- const childAttributes = parentNodes.map(node => {
346
+ const childAttributes = parentNodes.map((node) => {
313
347
  const nodeDoc = dom.parseFromString(node.toString(), 'application/xml');
314
348
  if (attributes.length === 0) {
315
349
  // @ts-ignore
316
350
  const childValues = select(fullChildXPath, nodeDoc).map((n) => n.nodeValue);
317
- if (childValues.length === 1) {
318
- return childValues[0];
319
- }
320
- return childValues;
351
+ return childValues.length === 1 ? childValues[0] : childValues;
321
352
  }
322
353
  if (attributes.length > 0) {
323
354
  // @ts-ignore
324
355
  const childValues = select(fullChildXPath, nodeDoc).map((n) => n.value);
325
- if (childValues.length === 1) {
326
- return childValues[0];
327
- }
328
- return childValues;
356
+ return childValues.length === 1 ? childValues[0] : childValues;
329
357
  }
330
358
  return null;
331
359
  });
332
- // aggregation
333
360
  const obj = zipObject(parentAttributes, childAttributes, false);
334
- return {
335
- ...result,
336
- [key]: obj
337
- };
361
+ return { ...result, [key]: obj };
338
362
  }
339
- // case: fetch entire content, only allow one existence
340
- /*
341
- {
342
- key: 'signature',
343
- localPath: ['AuthnRequest', 'Signature'],
344
- attributes: [],
345
- context: true
346
- }
347
- */
363
+ // 特殊 case: 获取整个节点内容 (原有逻辑)
348
364
  if (isEntire) {
349
- // @ts-expect-error misssing Node properties are not needed
365
+ // @ts-ignore
350
366
  const node = select(baseXPath, targetDoc);
351
367
  let value = null;
352
368
  if (node.length === 1) {
353
369
  value = node[0].toString();
354
370
  }
355
371
  if (node.length > 1) {
356
- value = node.map(n => n.toString());
372
+ value = node.map((n) => n.toString());
357
373
  }
358
- return {
359
- ...result,
360
- [key]: value
361
- };
374
+ return { ...result, [key]: value };
362
375
  }
363
- // case: multiple attribute
364
- /*
365
- {
366
- key: 'nameIDPolicy',
367
- localPath: ['AuthnRequest', 'NameIDPolicy'],
368
- attributes: ['Format', 'AllowCreate']
369
- }
370
- */
371
- if (attributes.length > 1) {
376
+ // 特殊 case: 多属性对象 (原有逻辑,非 listMode)
377
+ if (attributes.length > 1 && !listMode) {
372
378
  // @ts-ignore
373
- const baseNode = select(baseXPath, targetDoc).map(n => n.toString());
374
- const childXPath = `${buildAbsoluteXPath([last(localPath)])}${attributeXPath}`;
375
- const attributeValues = baseNode.map((node) => {
379
+ const baseNode = select(baseXPath, targetDoc).map((n) => n.toString());
380
+ const childXPath = `${buildAbsoluteXPath([last(currentLocalPath)])}${attributeXPath}`;
381
+ const attributeValues = baseNode.map((nodeStr) => {
376
382
  // @ts-ignore
377
- const nodeDoc = dom.parseFromString(node, 'application/xml');
383
+ const nodeDoc = dom.parseFromString(nodeStr, 'application/xml');
378
384
  // @ts-ignore
379
385
  const values = select(childXPath, nodeDoc).reduce((r, n) => {
380
386
  r[camelCase(n.name, { locale: 'en-us' })] = n.value;
@@ -387,49 +393,35 @@ export function extract(context, fields) {
387
393
  [key]: attributeValues.length === 1 ? attributeValues[0] : attributeValues
388
394
  };
389
395
  }
390
- // case: single attribute
391
- /*
392
- {
393
- key: 'statusCode',
394
- localPath: ['Response', 'Status', 'StatusCode'],
395
- attributes: ['Value'],
396
- }
397
- */
398
- if (attributes.length === 1) {
396
+ // 特殊 case: 单个属性 (原有逻辑)
397
+ if (attributes.length === 1 && !listMode) {
399
398
  const fullPath = `${baseXPath}${attributeXPath}`;
400
399
  // @ts-ignore
401
400
  const attributeValues = select(fullPath, targetDoc).map((n) => n.value);
402
- return {
403
- ...result,
404
- [key]: attributeValues[0]
405
- };
401
+ return { ...result, [key]: attributeValues[0] };
406
402
  }
407
- // case: zero attribute
408
- /*
409
- {
410
- key: 'issuer',
411
- localPath: ['AuthnRequest', 'Issuer'],
412
- attributes: []
413
- }
414
- */
415
- if (attributes.length === 0) {
403
+ // 特殊 case: 无属性/文本内容 (原有逻辑)
404
+ if (attributes.length === 0 && !listMode) {
416
405
  let attributeValue = null;
417
- // @ts-expect-error misssing Node properties are not needed
406
+ // @ts-ignore
418
407
  const node = select(baseXPath, targetDoc);
419
408
  if (node.length === 1) {
420
409
  const fullPath = `string(${baseXPath}${attributeXPath})`;
421
- // @ts-expect-error misssing Node properties are not needed
410
+ // @ts-ignore
422
411
  attributeValue = select(fullPath, targetDoc);
423
412
  }
424
413
  if (node.length > 1) {
425
414
  attributeValue = node.filter((n) => n.firstChild)
426
- .map((n) => n.firstChild.nodeValue);
415
+ .map((n) => n.firstChild?.nodeValue);
427
416
  }
428
- return {
429
- ...result,
430
- [key]: attributeValue
431
- };
417
+ return { ...result, [key]: attributeValue };
432
418
  }
433
419
  return result;
434
420
  }, {});
435
421
  }
422
+ export function extractIdp(context) {
423
+ return extract(context, idpMetadataFields);
424
+ }
425
+ export function extractSp(context) {
426
+ return extract(context, spMetadataFields);
427
+ }
@@ -17,7 +17,7 @@ import xmlEscape from 'xml-escape';
17
17
  import * as fs from 'fs';
18
18
  import { DOMParser } from '@xmldom/xmldom';
19
19
  const signatureAlgorithms = algorithms.signature;
20
- const digestAlgorithms = algorithms.digest;
20
+ const digestAlgorithms = algorithms.signatureToDigestMap;
21
21
  const certUse = wording.certUse;
22
22
  const urlParams = wording.urlParams;
23
23
  const libSaml = () => {
@@ -328,7 +328,7 @@ xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="{ID}"
328
328
  * @return {string} base64 encoded string
329
329
  */
330
330
  constructSAMLSignature(opts) {
331
- const { rawSamlMessage, referenceTagXPath, privateKey, privateKeyPass, signatureAlgorithm = signatureAlgorithms.RSA_SHA512, transformationAlgorithms = [
331
+ const { rawSamlMessage, referenceTagXPath, privateKey, privateKeyPass, signatureAlgorithm = signatureAlgorithms.RSA_SHA256, transformationAlgorithms = [
332
332
  'http://www.w3.org/2000/09/xmldsig#enveloped-signature',
333
333
  'http://www.w3.org/2001/10/xml-exc-c14n#',
334
334
  ], signingCert, signatureConfig, isBase64Output = true, isMessageSigned = false, } = opts;
@@ -926,7 +926,7 @@ xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="{ID}"
926
926
  verifier.update(octetString);
927
927
  const isValid = verifier.verify(utility.getPublicKeyPemFromCertificate(signCert), Buffer.isBuffer(signature) ? signature : Buffer.from(signature, 'base64'));
928
928
  return isValid
929
-
929
+
930
930
  },*/
931
931
  /**
932
932
  * @desc Verifies message signature
@@ -994,9 +994,11 @@ xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="{ID}"
994
994
  pem: Buffer.from(`-----BEGIN CERTIFICATE-----${targetEntityMetadata.getX509Certificate(certUse.encrypt)}-----END CERTIFICATE-----`),
995
995
  encryptionAlgorithm: sourceEntitySetting.dataEncryptionAlgorithm,
996
996
  keyEncryptionAlgorithm: sourceEntitySetting.keyEncryptionAlgorithm,
997
- keyEncryptionDigest: sourceEntitySetting.keyEncryptionDigest ?? 'sha256', //default sha256
997
+ keyEncryptionDigest: sourceEntitySetting.keyEncryptionDigest ?? 'sha1', //default sha256
998
998
  keyEncryptionMgf1: sourceEntitySetting.keyEncryptionMgf1 ?? 'sha256',
999
- disallowEncryptionWithInsecureAlgorithm: true,
999
+ disallowEncryptionWithInsecureAlgorithm: sourceEntitySetting.disallowEncryptionWithInsecureAlgorithm, // 禁止使用rsa-1_5 tripledes-cbc
1000
+ disallowInsecureEncryption: sourceEntitySetting.disallowInsecureEncryption, //禁aes cbc系列加密算法
1001
+ disallowInsecureHash: sourceEntitySetting.disallowInsecureHash, //禁止使用不安全的签名hash算法,不包括mgf1
1000
1002
  warnInsecureAlgorithm: true
1001
1003
  }, (err, res) => {
1002
1004
  if (err) {
@@ -1017,49 +1019,6 @@ xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="{ID}"
1017
1019
  }
1018
1020
  });
1019
1021
  },
1020
- /**
1021
- * @desc Decrypt the assertion section in Response
1022
- * @param {string} type only accept SAMLResponse to proceed decryption
1023
- * @param {Entity} here this entity
1024
- * @param {Entity} from from the entity where the message is sent
1025
- * @param {string} entireXML response in xml string format
1026
- * @return {function} a promise to get back the entire xml with decrypted assertion
1027
- */
1028
- decryptAssertion(here, entireXML) {
1029
- return new Promise((resolve, reject) => {
1030
- // Implement decryption first then check the signature
1031
- if (!entireXML) {
1032
- return reject(new Error('ERR_UNDEFINED_ASSERTION'));
1033
- }
1034
- // Perform encryption depends on the setting of where the message is sent, default is false
1035
- const hereSetting = here.entitySetting;
1036
- const { dom } = getContext();
1037
- const doc = dom.parseFromString(entireXML, 'application/xml');
1038
- // @ts-expect-error misssing Node properties are not needed
1039
- const encryptedAssertions = select("/*[contains(local-name(), 'Response')]/*[local-name(.)='EncryptedAssertion']", doc);
1040
- if (!Array.isArray(encryptedAssertions) || encryptedAssertions.length === 0) {
1041
- throw new Error('ERR_UNDEFINED_ENCRYPTED_ASSERTION');
1042
- }
1043
- if (encryptedAssertions.length > 1) {
1044
- throw new Error('ERR_MULTIPLE_ASSERTION');
1045
- }
1046
- const encAssertionNode = encryptedAssertions[0];
1047
- return xmlenc.decrypt(encAssertionNode.toString(), {
1048
- key: utility.readPrivateKey(hereSetting.encPrivateKey, hereSetting.encPrivateKeyPass),
1049
- }, (err, res) => {
1050
- if (err) {
1051
- return reject(new Error('ERR_EXCEPTION_OF_ASSERTION_DECRYPTION'));
1052
- }
1053
- if (!res) {
1054
- return reject(new Error('ERR_UNDEFINED_ENCRYPTED_ASSERTION'));
1055
- }
1056
- const rawAssertionDoc = dom.parseFromString(res, 'application/xml');
1057
- // @ts-ignore
1058
- doc.documentElement.replaceChild(rawAssertionDoc.documentElement, encAssertionNode);
1059
- return resolve([doc.toString(), res]);
1060
- });
1061
- });
1062
- },
1063
1022
  /**
1064
1023
  * 同步版本的断言解密函数
1065
1024
  */
@@ -1084,6 +1043,10 @@ xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="{ID}"
1084
1043
  // 使用同步方式处理解密
1085
1044
  xmlenc.decrypt(encAssertionNode.toString(), {
1086
1045
  key: utility.readPrivateKey(hereSetting.encPrivateKey, hereSetting.encPrivateKeyPass),
1046
+ /* disallowInsecureEncryption:hereSetting.disallowInsecureEncryption,//开启会禁止解密使用aes cbc系列加密算法的xml
1047
+ disallowDecryptionWithInsecureAlgorithm: hereSetting.disallowDecryptionWithInsecureAlgorithm,//开启会禁止解密使用rsa-1_5 tripledes-cbc加密算法的xml
1048
+ disallowInsecureHash: hereSetting.disallowInsecureHash,//开启会禁止解密使用 hsa1系列 hash算法的xml*/
1049
+ warnInsecureAlgorithm: true,
1087
1050
  }, (err, res) => {
1088
1051
  if (err) {
1089
1052
  throw new Error(err.message);
@@ -1178,6 +1141,7 @@ xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="{ID}"
1178
1141
  * @returns [解密后的完整 SOAP XML, 解密后的断言 XML]
1179
1142
  */
1180
1143
  async decryptAssertionSoap(self, entireXML) {
1144
+ let hereSetting = self.entitySetting;
1181
1145
  const { dom } = getContext();
1182
1146
  try {
1183
1147
  // 1. 解析 XML
@@ -1200,7 +1164,12 @@ xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="{ID}"
1200
1164
  const privateKey = utility.readPrivateKey(self.entitySetting.encPrivateKey, self.entitySetting.encPrivateKeyPass);
1201
1165
  // 4. 解密断言
1202
1166
  const decryptedAssertion = await new Promise((resolve, reject) => {
1203
- xmlenc.decrypt(encAssertionNode.toString(), { key: privateKey }, (err, result) => {
1167
+ xmlenc.decrypt(encAssertionNode.toString(), { key: privateKey,
1168
+ disallowInsecureEncryption: hereSetting.disallowInsecureEncryption, //开启会禁止解密使用aes cbc系列加密算法的xml
1169
+ disallowDecryptionWithInsecureAlgorithm: hereSetting.disallowDecryptionWithInsecureAlgorithm, //开启会禁止解密使用rsa-1_5 tripledes-cbc加密算法的xml
1170
+ disallowInsecureHash: hereSetting.disallowInsecureHash, //开启会禁止解密使用 hsa1系列 hash算法的xml
1171
+ warnInsecureAlgorithm: true,
1172
+ }, (err, result) => {
1204
1173
  if (err) {
1205
1174
  return reject(err);
1206
1175
  }
package/build/src/urn.js CHANGED
@@ -139,35 +139,98 @@ const messageConfigurations = {
139
139
  },
140
140
  };
141
141
  const algorithms = {
142
+ // 1. 签名算法定义 (SignatureMethod)
142
143
  signature: {
144
+ // ❌ 原文错误修正:ECDSA 不能用 rsa-sha256 的 URI
145
+ ECDSA_SHA256: 'http://www.w3.org/2007/05/xmldsig-more#ecdsa-sha256',
146
+ ECDSA_SHA384: 'http://www.w3.org/2007/05/xmldsig-more#ecdsa-sha384',
147
+ ECDSA_SHA512: 'http://www.w3.org/2007/05/xmldsig-more#ecdsa-sha512',
148
+ DSA_SHA1: 'http://www.w3.org/2000/09/xmldsig#dsa-sha1',
143
149
  RSA_SHA1: 'http://www.w3.org/2000/09/xmldsig#rsa-sha1',
144
- RSA_SHA256: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
150
+ RSA_SHA224: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha224',
151
+ RSA_SHA256: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', // 推荐
152
+ RSA_SHA384: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384',
145
153
  RSA_SHA512: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512',
154
+ // XML Signature 1.1 PSS 填充 (更安全)
155
+ RSA_PSS_SHA256: 'http://www.w3.org/2007/05/xmldsig-more#rsa-pss-sha256',
156
+ // EdDSA (Ed25519)
157
+ EDDSA_ED25519: 'http://www.w3.org/2007/05/xmldsig-more#eddsa-ed25519'
158
+ },
159
+ // 2. 摘要算法定义 (DigestMethod)
160
+ // 注意:这里直接使用标准推荐的 URI,SHA-2xx 系列推荐使用 xmlenc 命名空间
161
+ digest: {
162
+ SHA1: 'http://www.w3.org/2000/09/xmldsig#sha1',
163
+ SHA224: 'http://www.w3.org/2001/04/xmldsig-more#sha224', // 较少见,有时也用 xmlenc 但 xmldsig-more 更准确对应
164
+ SHA256: 'http://www.w3.org/2001/04/xmlenc#sha256', // ✅ 标准推荐
165
+ SHA384: 'http://www.w3.org/2001/04/xmlenc#sha384', // ✅ 标准推荐
166
+ SHA512: 'http://www.w3.org/2001/04/xmlenc#sha512' // ✅ 标准推荐
167
+ },
168
+ // 3. 映射关系表:给定一个签名算法 URI,它应该配合哪个摘要算法 URI?
169
+ // 这修复了你原代码中 digest 字段作为 "Map" 的意图
170
+ signatureToDigestMap: {
171
+ 'http://www.w3.org/2000/09/xmldsig#rsa-sha1': 'http://www.w3.org/2000/09/xmldsig#sha1',
172
+ 'http://www.w3.org/2000/09/xmldsig#dsa-sha1': 'http://www.w3.org/2000/09/xmldsig#sha1',
173
+ 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha224': 'http://www.w3.org/2001/04/xmldsig-more#sha224',
174
+ 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256': 'http://www.w3.org/2001/04/xmlenc#sha256',
175
+ 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384': 'http://www.w3.org/2001/04/xmlenc#sha384',
176
+ 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512': 'http://www.w3.org/2001/04/xmlenc#sha512',
177
+ 'http://www.w3.org/2007/05/xmldsig-more#ecdsa-sha256': 'http://www.w3.org/2001/04/xmlenc#sha256',
178
+ 'http://www.w3.org/2007/05/xmldsig-more#ecdsa-sha384': 'http://www.w3.org/2001/04/xmlenc#sha384',
179
+ 'http://www.w3.org/2007/05/xmldsig-more#ecdsa-sha512': 'http://www.w3.org/2001/04/xmlenc#sha512',
180
+ 'http://www.w3.org/2007/05/xmldsig-more#rsa-pss-sha256': 'http://www.w3.org/2001/04/xmlenc#sha256',
181
+ // EdDSA 比较特殊,它内部硬编码了 SHA-512,但在 XML 结构中如果需要显式声明 DigestMethod,通常指向 SHA-512
182
+ 'http://www.w3.org/2007/05/xmldsig-more#eddsa-ed25519': 'http://www.w3.org/2001/04/xmlenc#sha512'
146
183
  },
147
184
  encryption: {
148
185
  data: {
149
- AES_128: 'http://www.w3.org/2001/04/xmlenc#aes128-cbc',
150
- AES_256: 'http://www.w3.org/2001/04/xmlenc#aes256-cbc',
186
+ // --- CBC 模式 (XML Enc 1.0 - 兼容性最好) ---
187
+ AES_128_CBC: 'http://www.w3.org/2001/04/xmlenc#aes128-cbc',
188
+ AES_192_CBC: 'http://www.w3.org/2001/04/xmlenc#aes192-cbc',
189
+ AES_256_CBC: 'http://www.w3.org/2001/04/xmlenc#aes256-cbc',
190
+ // --- GCM 模式 (XML Enc 1.1 - 推荐,提供完整性保护) ---
191
+ AES_128_GCM: 'http://www.w3.org/2009/xmlenc11#aes128-gcm',
192
+ AES_192_GCM: 'http://www.w3.org/2009/xmlenc11#aes192-gcm',
151
193
  AES_256_GCM: 'http://www.w3.org/2009/xmlenc11#aes256-gcm',
152
- TRI_DEC: 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc',
153
- AES_128_GCM: 'http://www.w3.org/2009/xmlenc11#aes128-gcm'
194
+ // --- CTR 模式 (XML Enc 1.1) ---
195
+ AES_128_CTR: 'http://www.w3.org/2009/xmlenc11#aes128-ctr',
196
+ AES_192_CTR: 'http://www.w3.org/2009/xmlenc11#aes192-ctr',
197
+ AES_256_CTR: 'http://www.w3.org/2009/xmlenc11#aes256-ctr',
198
+ // --- 旧算法 (不推荐,仅用于遗留系统) ---
199
+ TRIPLE_DES: 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc'
154
200
  },
201
+ /**
202
+ * 密钥加密算法 (用于加密生成的 AES 会话密钥)
203
+ * 这里包含了 RSA-OAEP 和 AES Key Wrap
204
+ */
155
205
  key: {
206
+ // --- RSA OAEP (推荐) ---
207
+ // 默认使用 SHA-1 的 OAEP (XML Enc 1.0)
156
208
  RSA_OAEP_MGF1P: 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p',
209
+ // XML Enc 1.1 的通用 OAEP (通常配合 DigestMethod 参数使用 SHA-256)
210
+ RSA_OAEP: 'http://www.w3.org/2009/xmlenc11#rsa-oaep',
211
+ // --- RSA PKCS#1 v1.5 (旧标准,不推荐,但广泛存在) ---
157
212
  RSA_1_5: 'http://www.w3.org/2001/04/xmlenc#rsa-1_5',
213
+ // --- AES Key Wrap (用于对称密钥加密对称密钥的场景) ---
214
+ AES_128_KW: 'http://www.w3.org/2001/04/xmlenc#kw-aes128',
215
+ AES_192_KW: 'http://www.w3.org/2001/04/xmlenc#kw-aes192',
216
+ AES_256_KW: 'http://www.w3.org/2001/04/xmlenc#kw-aes256',
217
+ // --- AES GCM Key Wrap (XML Enc 1.1) ---
218
+ AES_128_GCM_KW: 'http://www.w3.org/2009/xmlenc11#aes128-gcmkw',
219
+ AES_192_GCM_KW: 'http://www.w3.org/2009/xmlenc11#aes192-gcmkw',
220
+ AES_256_GCM_KW: 'http://www.w3.org/2009/xmlenc11#aes256-gcmkw',
158
221
  },
159
222
  },
160
- digest: {
161
- 'http://www.w3.org/2000/09/xmldsig#rsa-sha1': 'http://www.w3.org/2000/09/xmldsig#sha1',
162
- 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256': 'http://www.w3.org/2001/04/xmlenc#sha256',
163
- 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384': 'http://www.w3.org/2001/04/xmlenc#sha384',
164
- 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512': 'http://www.w3.org/2001/04/xmlenc#sha512', // support hashing algorithm sha512 in xml-crypto after 0.8.0
165
- 'http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1': 'http://www.w3.org/2001/04/xmlenc#sha256',
166
- 'http://www.w3.org/2007/05/xmldsig-more#sha384-rsa-MGF1': 'http://www.w3.org/2001/04/xmlenc#sha384',
167
- 'http://www.w3.org/2007/05/xmldsig-more#sha512-rsa-MGF1': 'http://www.w3.org/2001/04/xmlenc#sha512', // support hashing algorithm sha512 in xml-crypto after 0.8.0
168
- 'http://www.w3.org/2007/05/xmldsig-more#eddsa-ed25519': 'http://www.w3.org/2001/04/xmlenc#sha512'
169
- },
170
223
  };
224
+ // 使用示例:
225
+ // 如果你选择了 RSA_SHA256 签名
226
+ const selectedSigAlg = algorithms.signature.RSA_SHA256;
227
+ // 自动获取对应的摘要算法
228
+ const requiredDigestAlg = algorithms.signatureToDigestMap[selectedSigAlg];
229
+ console.log(`Signature: ${selectedSigAlg}`);
230
+ console.log(`Required Digest: ${requiredDigestAlg}`);
231
+ // 输出:
232
+ // Signature: http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
233
+ // Required Digest: http://www.w3.org/2001/04/xmlenc#sha256
171
234
  export var ParserType;
172
235
  (function (ParserType) {
173
236
  ParserType["SAMLRequest"] = "SAMLRequest";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "samlesa",
3
- "version": "3.2.1",
3
+ "version": "3.3.0",
4
4
  "description": "High-level API for Single Sign On (SAML 2.0) baseed on samlify ",
5
5
  "main": "build/index.js",
6
6
  "keywords": [
@@ -55,7 +55,7 @@
55
55
  "xml": "^1.0.1",
56
56
  "xml-crypto-next": "^7.0.0",
57
57
  "xml-crypto": "^6.1.2",
58
- "xml-encryption-next": "^4.5.0",
58
+ "xml-encryption-next": "^4.6.0",
59
59
  "xml-escape": "^1.1.0",
60
60
  "xml2js": "^0.6.2",
61
61
  "xmllint-wasm": "^5.1.0",
@@ -1,53 +1,27 @@
1
1
  interface ExtractorField {
2
2
  key: string;
3
- localPath: string[] | string[][];
4
- attributes: string[];
3
+ localPath?: string[] | string[][];
4
+ attributes?: string[];
5
5
  index?: string[];
6
6
  attributePath?: string[];
7
7
  context?: boolean;
8
+ listMode?: boolean;
9
+ shortcut?: string;
8
10
  }
9
11
  export type ExtractorFields = ExtractorField[];
10
12
  export declare const loginRequestFields: ExtractorFields;
11
- export declare const artifactResolveFields: ({
12
- key: string;
13
- localPath: string[];
14
- attributes: string[];
15
- context?: undefined;
16
- } | {
17
- key: string;
18
- localPath: string[];
19
- attributes: never[];
20
- context: boolean;
21
- })[];
22
- export declare const artifactResponseFields: ({
23
- key: string;
24
- localPath: string[];
25
- attributes: string[];
26
- context?: undefined;
27
- } | {
28
- key: string;
29
- localPath: string[];
30
- attributes: never[];
31
- context: boolean;
32
- })[];
33
- export declare const loginResponseStatusFields: {
34
- key: string;
35
- localPath: string[];
36
- attributes: string[];
37
- }[];
38
- export declare const loginArtifactResponseStatusFields: {
39
- key: string;
40
- localPath: string[];
41
- attributes: string[];
42
- }[];
43
- export declare const logoutResponseStatusFields: {
44
- key: string;
45
- localPath: string[];
46
- attributes: string[];
47
- }[];
13
+ export declare const artifactResolveFields: ExtractorFields;
14
+ export declare const artifactResponseFields: ExtractorFields;
15
+ export declare const loginResponseStatusFields: ExtractorFields;
16
+ export declare const loginArtifactResponseStatusFields: ExtractorFields;
17
+ export declare const logoutResponseStatusFields: ExtractorFields;
48
18
  export declare const loginResponseFields: ((assertion: any) => ExtractorFields);
49
19
  export declare const logoutRequestFields: ExtractorFields;
50
20
  export declare const logoutResponseFields: ExtractorFields;
51
- export declare function extract(context: string, fields: any): any;
21
+ export declare const idpMetadataFields: ExtractorFields;
22
+ export declare const spMetadataFields: ExtractorFields;
23
+ export declare function extract(context: string, fields: ExtractorFields): any;
24
+ export declare function extractIdp(context: string): any;
25
+ export declare function extractSp(context: string): any;
52
26
  export {};
53
27
  //# sourceMappingURL=extractor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/extractor.ts"],"names":[],"mappings":"AAKA,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,eAAe,GAAG,cAAc,EAAE,CAAC;AA4B/C,eAAO,MAAM,kBAAkB,EAAE,eA2BhC,CAAC;AACF,eAAO,MAAM,qBAAqB;;;;;;;;;;IAiBjC,CAAC;AACF,eAAO,MAAM,sBAAsB;;;;;;;;;;IAiBlC,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;GAWrC,CAAC;AAEF,eAAO,MAAM,iCAAiC;;;;GAW7C,CAAC;AAGF,eAAO,MAAM,0BAA0B;;;;GAWtC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,KAAK,eAAe,CAkErE,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eA2BjC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAiBlC,CAAC;AAEF,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,KAAA,OA6M9C"}
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/extractor.ts"],"names":[],"mappings":"AAMA,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,eAAe,GAAG,cAAc,EAAE,CAAC;AAgC/C,eAAO,MAAM,kBAAkB,EAAE,eAMhC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,eAKnC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAKpC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,eAGvC,CAAC;AAEF,eAAO,MAAM,iCAAiC,EAAE,eAG/C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eAGxC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,KAAK,eAAe,CAWrE,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAMjC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAIlC,CAAC;AAKF,eAAO,MAAM,iBAAiB,EAAE,eAiI/B,CAAC;AAQF,eAAO,MAAM,gBAAgB,EAAE,eAmB9B,CAAC;AAEF,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,OAiN/D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,OAEzC;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,OAExC"}
@@ -257,15 +257,6 @@ declare const _default: {
257
257
  * @return {Promise} a promise to resolve the finalized xml
258
258
  */
259
259
  encryptAssertion(sourceEntity: any, targetEntity: any, xml?: string): Promise<string>;
260
- /**
261
- * @desc Decrypt the assertion section in Response
262
- * @param {string} type only accept SAMLResponse to proceed decryption
263
- * @param {Entity} here this entity
264
- * @param {Entity} from from the entity where the message is sent
265
- * @param {string} entireXML response in xml string format
266
- * @return {function} a promise to get back the entire xml with decrypted assertion
267
- */
268
- decryptAssertion(here: any, entireXML: string): Promise<[string, any]>;
269
260
  /**
270
261
  * 同步版本的断言解密函数
271
262
  */
@@ -1 +1 @@
1
- {"version":3,"file":"libsaml.d.ts","sourceRoot":"","sources":["../../src/libsaml.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAerD;;;;GAIG;AAGH,MAAM,WAAW,oBAAoB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,GAAG,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,wBAAwB;IACrC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IAEnB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,gCAAgC;IAC7C,0BAA0B,CAAC,EAAE,0BAA0B,CAAC;IACxD,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC3D,UAAU,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACtC,mBAAmB,CAAC,EAAE,gCAAgC,CAAC;CAC1D;AAED,MAAM,WAAW,0BAA2B,SAAQ,gBAAgB;CACnE;AAED,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;CAC1D;AAED,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;CAC7D;AAED,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;CAC9D;AAED,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;CAC/D;AAED,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;AAE9C,MAAM,WAAW,YAAY;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC7B,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9C,WAAW,EAAE,CAAC,KAAK,KAAA,EAAE,YAAY,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IACvD,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,MAAM,CAAC;IAC/D,yBAAyB,EAAE,CAAC,UAAU,EAAE,sBAAsB,EAAE,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,0BAA0B,KAAK,MAAM,CAAC;IAC1K,sBAAsB,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,MAAM,CAAC;IAC/D,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,wBAAwB,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACjF,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,KAAK,EAAE,CAAC;IAC7D,yBAAyB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAE5I,sBAAsB,EAAE,CAAC,QAAQ,KAAA,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IACzH,UAAU,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACrE,gBAAgB,EAAE,CAAC,YAAY,KAAA,EAAE,YAAY,KAAA,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrF,gBAAgB,EAAE,CAAC,IAAI,KAAA,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAEtE,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACpD,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAEnD,gBAAgB,EAAE,GAAG,CAAC;IACtB,2BAA2B,EAAE,oBAAoB,CAAC;IAClD,4BAA4B,EAAE,qBAAqB,CAAC;IACpD,iCAAiC,EAAE,0BAA0B,CAAC;IAC9D,wBAAwB,EAAE,iBAAiB,CAAC;IAC5C,4BAA4B,EAAE,qBAAqB,CAAC;IACpD,6BAA6B,EAAE,sBAAsB,CAAC;CACzD;;6CAgO8C,OAAO,KAAG,MAAM;gCAxNxB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDA8BkB,MAAM;;;;IAuO7D;;;;;OAKG;+BACwB,MAAM,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAS9E;;;;;;OAMG;IACH,eAAe;6CAC0B,GAAG,EAAE,GAAG,MAAM;IA0CvD;;;OAGG;iCAC0B;QACzB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;QAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,WAAW,EAAE,GAAG,CAAC;QACjB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,cAAc,EAAE,GAAG,CAAC;QACpB,wBAAwB,CAAC,EAAG,MAAM,EAAE,GAAG,SAAS,CAAC;QACjD,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE;gBAAE,SAAS,EAAE,MAAM,CAAC;gBAAC,MAAM,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KACvF,GAAE,MAAM;2CAkD8B,MAAM,mBAAmB,MAAM;;;;;;;;;;;;;IAoCtE;;;;;;OAMG;yBAEsB,MAAM,QAAQ,wBAAwB,QAAQ,GAAG;;;;;;;;;;;;;;6BA4WjD,MAAM,QAAQ,wBAAwB;IAoK/D;;;;;OAKG;0BACmB,MAAM,cAAc,MAAM,GAAG,MAAM,GAAG,YAAY;IAsBxE;;;;;;;;OAQG;2CAEc,MAAM,OACd,MAAM,eACE,MAAM,aACR,OAAO,qBACC,MAAM;IA8B7B;;;;;;;OAOG;uDAGc,MAAM,aACR,MAAM,GAAG,MAAM,oBACR,MAAM;IAO5B;;;;OAIG;gCACyB,MAAM,oBAAmB,GAAG;;;;IAWxD;;;;;;OAMG;iEAEgD,MAAM;IAsDzD;;;;;;;OAOG;2CAC+B,MAAM;IAoCxC;;OAEG;IACH;;OAEG;+CACmC,MAAM,SAAS,wBAAwB;;;;;;IAsH7E;;;;;OAKG;+BAC8B,GAAG,aAAa,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAuEnF;;OAEG;sBACqB,MAAM,SAAQ,OAAO;;AA8BrD,wBAAyB"}
1
+ {"version":3,"file":"libsaml.d.ts","sourceRoot":"","sources":["../../src/libsaml.ts"],"names":[],"mappings":"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"}
@@ -133,33 +133,67 @@ declare const messageConfigurations: {
133
133
  };
134
134
  declare const algorithms: {
135
135
  signature: {
136
+ ECDSA_SHA256: string;
137
+ ECDSA_SHA384: string;
138
+ ECDSA_SHA512: string;
139
+ DSA_SHA1: string;
136
140
  RSA_SHA1: string;
141
+ RSA_SHA224: string;
137
142
  RSA_SHA256: string;
143
+ RSA_SHA384: string;
138
144
  RSA_SHA512: string;
145
+ RSA_PSS_SHA256: string;
146
+ EDDSA_ED25519: string;
147
+ };
148
+ digest: {
149
+ SHA1: string;
150
+ SHA224: string;
151
+ SHA256: string;
152
+ SHA384: string;
153
+ SHA512: string;
154
+ };
155
+ signatureToDigestMap: {
156
+ 'http://www.w3.org/2000/09/xmldsig#rsa-sha1': string;
157
+ 'http://www.w3.org/2000/09/xmldsig#dsa-sha1': string;
158
+ 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha224': string;
159
+ 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256': string;
160
+ 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384': string;
161
+ 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512': string;
162
+ 'http://www.w3.org/2007/05/xmldsig-more#ecdsa-sha256': string;
163
+ 'http://www.w3.org/2007/05/xmldsig-more#ecdsa-sha384': string;
164
+ 'http://www.w3.org/2007/05/xmldsig-more#ecdsa-sha512': string;
165
+ 'http://www.w3.org/2007/05/xmldsig-more#rsa-pss-sha256': string;
166
+ 'http://www.w3.org/2007/05/xmldsig-more#eddsa-ed25519': string;
139
167
  };
140
168
  encryption: {
141
169
  data: {
142
- AES_128: string;
143
- AES_256: string;
144
- AES_256_GCM: string;
145
- TRI_DEC: string;
170
+ AES_128_CBC: string;
171
+ AES_192_CBC: string;
172
+ AES_256_CBC: string;
146
173
  AES_128_GCM: string;
174
+ AES_192_GCM: string;
175
+ AES_256_GCM: string;
176
+ AES_128_CTR: string;
177
+ AES_192_CTR: string;
178
+ AES_256_CTR: string;
179
+ TRIPLE_DES: string;
147
180
  };
181
+ /**
182
+ * 密钥加密算法 (用于加密生成的 AES 会话密钥)
183
+ * 这里包含了 RSA-OAEP 和 AES Key Wrap
184
+ */
148
185
  key: {
149
186
  RSA_OAEP_MGF1P: string;
187
+ RSA_OAEP: string;
150
188
  RSA_1_5: string;
189
+ AES_128_KW: string;
190
+ AES_192_KW: string;
191
+ AES_256_KW: string;
192
+ AES_128_GCM_KW: string;
193
+ AES_192_GCM_KW: string;
194
+ AES_256_GCM_KW: string;
151
195
  };
152
196
  };
153
- digest: {
154
- 'http://www.w3.org/2000/09/xmldsig#rsa-sha1': string;
155
- 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256': string;
156
- 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384': string;
157
- 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512': string;
158
- 'http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1': string;
159
- 'http://www.w3.org/2007/05/xmldsig-more#sha384-rsa-MGF1': string;
160
- 'http://www.w3.org/2007/05/xmldsig-more#sha512-rsa-MGF1': string;
161
- 'http://www.w3.org/2007/05/xmldsig-more#eddsa-ed25519': string;
162
- };
163
197
  };
164
198
  export declare enum ParserType {
165
199
  SAMLRequest = "SAMLRequest",
@@ -1 +1 @@
1
- {"version":3,"file":"urn.d.ts","sourceRoot":"","sources":["../../src/urn.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oBAAY,gBAAgB;IACxB,QAAQ,uDAAuD;IAC/D,IAAI,mDAAmD;IACvD,UAAU,8DAA8D;IACxE,QAAQ,uDAAuD;CAClE;AAED,oBAAY,qBAAqB;IAC7B,GAAG,sBAAsB;IACzB,GAAG,sBAAsB;CAC5B;AAED,oBAAY,UAAU;IAElB,OAAO,+CAA+C;IACtD,SAAS,iDAAiD;IAC1D,SAAS,iDAAiD;IAC1D,eAAe,uDAAuD;IAEtE,UAAU,mDAAmD;IAC7D,sBAAsB,8DAA8D;IACpF,mBAAmB,2DAA2D;IAC9E,cAAc,sDAAsD;IACpE,cAAc,sDAAsD;IACpE,SAAS,iDAAiD;IAC1D,cAAc,sDAAsD;IACpE,aAAa,qDAAqD;IAClE,kBAAkB,0DAA0D;IAC5E,aAAa,qDAAqD;IAClE,kBAAkB,0DAA0D;IAC5E,wBAAwB,gEAAgE;IACxF,qBAAqB,6DAA6D;IAClF,oBAAoB,4DAA4D;IAChF,qBAAqB,6DAA6D;IAClF,gBAAgB,wDAAwD;IACxE,kBAAkB,0DAA0D;IAC5E,gBAAgB,wDAAwD;IACxE,kBAAkB,0DAA0D;CAC/E;AAED,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDd,CAAC;AAEF,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BT,CAAC;AAEF,QAAA,MAAM,qBAAqB;;;;;CAK1B,CAAC;AAEF,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCf,CAAC;AAEF,oBAAY,UAAU;IAClB,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;CACpC;AAED,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;CAyBZ,CAAC;AAIF,QAAA,MAAM,aAAa;;;;CAIlB,CAAC;AAEF,OAAO,EAAC,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAC,CAAC"}
1
+ {"version":3,"file":"urn.d.ts","sourceRoot":"","sources":["../../src/urn.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oBAAY,gBAAgB;IAC1B,QAAQ,uDAAuD;IAC/D,IAAI,mDAAmD;IACvD,UAAU,8DAA8D;IACxE,QAAQ,uDAAuD;CAChE;AAED,oBAAY,qBAAqB;IAC/B,GAAG,sBAAsB;IACzB,GAAG,sBAAsB;CAC1B;AAED,oBAAY,UAAU;IAEpB,OAAO,+CAA+C;IACtD,SAAS,iDAAiD;IAC1D,SAAS,iDAAiD;IAC1D,eAAe,uDAAuD;IAEtE,UAAU,mDAAmD;IAC7D,sBAAsB,8DAA8D;IACpF,mBAAmB,2DAA2D;IAC9E,cAAc,sDAAsD;IACpE,cAAc,sDAAsD;IACpE,SAAS,iDAAiD;IAC1D,cAAc,sDAAsD;IACpE,aAAa,qDAAqD;IAClE,kBAAkB,0DAA0D;IAC5E,aAAa,qDAAqD;IAClE,kBAAkB,0DAA0D;IAC5E,wBAAwB,gEAAgE;IACxF,qBAAqB,6DAA6D;IAClF,oBAAoB,4DAA4D;IAChF,qBAAqB,6DAA6D;IAClF,gBAAgB,wDAAwD;IACxE,kBAAkB,0DAA0D;IAC5E,gBAAgB,wDAAwD;IACxE,kBAAkB,0DAA0D;CAC7E;AAED,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDd,CAAC;AAEF,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BT,CAAC;AAEF,QAAA,MAAM,qBAAqB;;;;;CAK1B,CAAC;AAEF,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA2EZ;;;WAGG;;;;;;;;;;;;;CAwBN,CAAC;AAcF,oBAAY,UAAU;IACpB,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;CAClC;AAED,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;CAyBZ,CAAC;AAIF,QAAA,MAAM,aAAa;;;;CAIlB,CAAC;AAEF,OAAO,EAAC,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAC,CAAC"}