samlesa 4.3.5 → 4.5.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.
@@ -87,7 +87,7 @@ function base64LoginRequest(referenceTagXPath, entity, customTagReplacement) {
87
87
  * @param AttributeStatement
88
88
  * @param idpInit
89
89
  */
90
- async function base64LoginResponse({ requestInfo = {}, entity, user = {}, customTagReplacement, encryptThenSign = false, AttributeStatement = [], idpInit }) {
90
+ async function base64LoginResponse({ requestInfo = {}, entity, user = {}, customTagReplacement, encryptThenSign = false, AttributeStatement = [], idpInit, destinationBinding = binding.post, }) {
91
91
  const idpSetting = entity.idp.entitySetting;
92
92
  const spSetting = entity.sp.entitySetting;
93
93
  // @ts-ignore
@@ -100,7 +100,9 @@ async function base64LoginResponse({ requestInfo = {}, entity, user = {}, custom
100
100
  const nameIDFormat = idpSetting.nameIDFormat;
101
101
  const selectedNameIDFormat = Array.isArray(nameIDFormat) ? nameIDFormat[0] : namespace.format.unspecified;
102
102
  if (metadata && metadata.idp && metadata.sp) {
103
- const base = metadata.sp.getAssertionConsumerService(binding.post);
103
+ const base = destinationBinding === binding.artifact
104
+ ? metadata.sp.getAssertionConsumerService(binding.artifact, { mode: 'lenient' })
105
+ : metadata.sp.getAssertionConsumerService(binding.post);
104
106
  let rawSamlResponse;
105
107
  const nowTime = new Date();
106
108
  const spEntityID = metadata.sp.getEntityID();
@@ -108,7 +110,9 @@ async function base64LoginResponse({ requestInfo = {}, entity, user = {}, custom
108
110
  oneMinutesLaterTime.setMinutes(oneMinutesLaterTime.getMinutes() + 5);
109
111
  const OneMinutesLater = oneMinutesLaterTime.toISOString();
110
112
  const now = nowTime.toISOString();
111
- const acl = metadata.sp.getAssertionConsumerService(binding.post);
113
+ const acl = destinationBinding === binding.artifact
114
+ ? metadata.sp.getAssertionConsumerService(binding.artifact, { mode: 'lenient' })
115
+ : metadata.sp.getAssertionConsumerService(binding.post);
112
116
  // @ts-ignore
113
117
  const sessionID = idpSetting?.generateID() ?? `_${randomUUID()}`;
114
118
  const sessionIndex = 'session' + sessionID; // 这个是当前系统的会话索引,用于单点注销
@@ -3,8 +3,6 @@
3
3
  * @author tngan
4
4
  * @desc Declares the actions taken by identity provider
5
5
  */
6
- import { wording, } from './urn.js';
7
- const binding = wording.binding;
8
6
  import Entity from './entity.js';
9
7
  import { namespace } from './urn.js';
10
8
  import postBinding from './binding-post.js';
@@ -68,7 +66,7 @@ export class IdentityProvider extends Entity {
68
66
  sp,
69
67
  }, user, relayState, customTagReplacement, AttributeStatement);
70
68
  case namespace.binding.artifact:
71
- context = await artifactBinding.soapLoginResponse({
69
+ context = await artifactBinding.createLoginResponse({
72
70
  requestInfo,
73
71
  entity: {
74
72
  idp: this,
@@ -91,6 +89,49 @@ export class IdentityProvider extends Entity {
91
89
  type: 'SAMLResponse'
92
90
  };
93
91
  }
92
+ createArtifactResolveRequest(sp, artifact) {
93
+ return artifactBinding.createArtifactResolveRequest({
94
+ requester: this,
95
+ responder: sp,
96
+ artifact,
97
+ });
98
+ }
99
+ async createArtifactResolveResponse(params) {
100
+ const { sp, samlMessage, requestInfo = {}, user = {}, customTagReplacement, encryptThenSign = false, AttributeStatement = [], idpInit = false, inResponseTo = '', } = params;
101
+ const resolvedMessage = samlMessage ?? (await artifactBinding.createLoginResponse({
102
+ requestInfo,
103
+ entity: {
104
+ idp: this,
105
+ sp,
106
+ },
107
+ user,
108
+ customTagReplacement,
109
+ encryptThenSign,
110
+ AttributeStatement,
111
+ idpInit,
112
+ })).samlContent;
113
+ return artifactBinding.createArtifactResolveResponse({
114
+ requester: sp,
115
+ responder: this,
116
+ inResponseTo,
117
+ samlMessage: resolvedMessage,
118
+ });
119
+ }
120
+ parseArtifactResolveRequest(sp, xml) {
121
+ return artifactBinding.parseArtifactResolveRequest({
122
+ requester: sp,
123
+ responder: this,
124
+ xml,
125
+ });
126
+ }
127
+ parseArtifactResolveResponse(sp, xml, inResponseTo) {
128
+ return artifactBinding.parseArtifactResolveResponse({
129
+ requester: this,
130
+ responder: sp,
131
+ xml,
132
+ inResponseTo,
133
+ });
134
+ }
94
135
  /**
95
136
  * Validation of the parsed URL parameters
96
137
  * @param sp ServiceProvider instance
@@ -98,6 +139,13 @@ export class IdentityProvider extends Entity {
98
139
  * @param req RequesmessageSigningOrderst
99
140
  */
100
141
  parseLoginRequest(sp, binding, req) {
142
+ if (binding === namespace.binding.artifact || binding === 'artifact') {
143
+ return artifactBinding.parseLoginRequest({
144
+ idp: this,
145
+ sp,
146
+ request: req,
147
+ });
148
+ }
101
149
  const self = this;
102
150
  return flow({
103
151
  from: sp,
@@ -61,7 +61,7 @@ export class ServiceProvider extends Entity {
61
61
  context = simpleSignBinding.base64LoginRequest({ idp, sp: this }, customTagReplacement);
62
62
  break;
63
63
  case nsBinding.artifact:
64
- context = artifactBinding.soapLoginRequest("/*[local-name(.)='AuthnRequest']", {
64
+ context = artifactBinding.createLoginRequest("/*[local-name(.)='AuthnRequest']", {
65
65
  idp,
66
66
  sp: this
67
67
  }, customTagReplacement);
@@ -76,14 +76,24 @@ export class ServiceProvider extends Entity {
76
76
  type: 'SAMLRequest',
77
77
  };
78
78
  }
79
- async createLoginSoapRequest(idp, binding = 'artifact', config) {
80
- const context = await artifactBinding.soapLoginRequest("/*[local-name(.)='AuthnRequest']", {
79
+ createArtifactResolveRequest(idp, artifact) {
80
+ return artifactBinding.createArtifactResolveRequest({
81
+ requester: this,
82
+ responder: idp,
83
+ artifact,
84
+ });
85
+ }
86
+ async createArtifactResolveResponse(idp, config) {
87
+ const samlMessage = config?.samlMessage ?? artifactBinding.createLoginRequest("/*[local-name(.)='AuthnRequest']", {
81
88
  idp,
82
89
  sp: this,
83
- inResponse: config?.inResponseTo,
84
- relayState: config?.relayState,
85
- }, config?.customTagReplacement);
86
- return context;
90
+ }, config?.customTagReplacement).samlContent;
91
+ return artifactBinding.createArtifactResolveResponse({
92
+ requester: idp,
93
+ responder: this,
94
+ inResponseTo: config?.inResponseTo || '',
95
+ samlMessage,
96
+ });
87
97
  }
88
98
  /**
89
99
  * @desc Validation of the parsed the URL parameters
@@ -92,6 +102,13 @@ export class ServiceProvider extends Entity {
92
102
  * @param {request} req request
93
103
  */
94
104
  parseLoginResponse(idp, binding, request) {
105
+ if (binding === namespace.binding.artifact || binding === 'artifact') {
106
+ return artifactBinding.parseLoginResponse({
107
+ idp,
108
+ sp: this,
109
+ request,
110
+ });
111
+ }
95
112
  const self = this;
96
113
  return flow({
97
114
  from: idp,
@@ -103,31 +120,19 @@ export class ServiceProvider extends Entity {
103
120
  request: request
104
121
  });
105
122
  }
106
- /**
107
- * @desc Parse and validate Artifact Resolve request
108
- * @param {IdentityProvider} idp object of identity provider
109
- * @param {string} xml SOAP request XML string
110
- */
111
- parseLoginRequestResolve(idp, xml) {
112
- const self = this;
113
- return artifactBinding.parseLoginRequestResolve({
114
- idp: idp,
115
- sp: self,
116
- xml: xml
123
+ parseArtifactResolveRequest(idp, xml) {
124
+ return artifactBinding.parseArtifactResolveRequest({
125
+ requester: idp,
126
+ responder: this,
127
+ xml,
117
128
  });
118
129
  }
119
- /**
120
- * @desc Resolve SAML Response by Artifact ID
121
- * @param {IdentityProvider} idp object of identity provider
122
- * @param {string} art Artifact string
123
- * @param {request} req request
124
- */
125
- parseLoginResponseResolve(idp, art, request) {
126
- const self = this;
127
- return artifactBinding.parseLoginResponseResolve({
128
- idp: idp,
129
- sp: self,
130
- art: art
130
+ parseArtifactResolveResponse(idp, xml, inResponseTo) {
131
+ return artifactBinding.parseArtifactResolveResponse({
132
+ requester: this,
133
+ responder: idp,
134
+ xml,
135
+ inResponseTo,
131
136
  });
132
137
  }
133
138
  }
@@ -140,10 +140,27 @@ export const artifactResolveFields = [
140
140
  },
141
141
  ];
142
142
  export const artifactResponseFields = [
143
- { key: 'request', localPath: ['Envelope', 'Body', 'ArtifactResolve'], attributes: ['ID', 'IssueInstant', 'Version'] },
144
- { key: 'issuer', localPath: ['Envelope', 'Body', 'ArtifactResolve', 'Issuer'], attributes: [] },
145
- { key: 'Artifact', localPath: ['Envelope', 'Body', 'ArtifactResolve', 'Artifact'], attributes: [] },
146
- { key: 'signature', localPath: ['Envelope', 'Body', 'ArtifactResolve', 'Signature'], attributes: [], context: true },
143
+ {
144
+ key: 'response',
145
+ localPath: ['Envelope', 'Body', 'ArtifactResponse'],
146
+ attributes: ['ID', 'IssueInstant', 'Version', 'InResponseTo', 'Destination']
147
+ },
148
+ {
149
+ key: 'issuer',
150
+ localPath: ['Envelope', 'Body', 'ArtifactResponse', 'Issuer'],
151
+ attributes: []
152
+ },
153
+ {
154
+ key: 'status',
155
+ localPath: ['Envelope', 'Body', 'ArtifactResponse', 'Status', 'StatusCode'],
156
+ attributes: ['Value']
157
+ },
158
+ {
159
+ key: 'signature',
160
+ localPath: ['Envelope', 'Body', 'ArtifactResponse', 'Signature'],
161
+ attributes: [],
162
+ context: true
163
+ },
147
164
  ];
148
165
  export const loginResponseStatusFields = [
149
166
  { key: 'top', localPath: ['Response', 'Status', 'StatusCode'], attributes: ['Value'] },
@@ -160,6 +177,7 @@ export const logoutResponseStatusFields = [
160
177
  export const loginResponseFields = assertion => [
161
178
  { key: 'conditions', localPath: ['Assertion', 'Conditions'], attributes: ['NotBefore', 'NotOnOrAfter'], shortcut: assertion },
162
179
  { key: 'response', localPath: ['Response'], attributes: ['ID', 'IssueInstant', 'Destination', 'InResponseTo', 'Version'] },
180
+ { key: 'responseIssuer', localPath: ['Response', 'Issuer'], attributes: [] },
163
181
  { key: 'audience', localPath: ['Assertion', 'Conditions', 'AudienceRestriction', 'Audience'], attributes: [], shortcut: assertion },
164
182
  { key: 'issuer', localPath: ['Assertion', 'Issuer'], attributes: [], shortcut: assertion },
165
183
  { key: 'nameID', localPath: ['Assertion', 'Subject', 'NameID'], attributes: [], shortcut: assertion },