samlify 2.12.0 → 2.13.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.
- package/README.md +1 -1
- package/build/src/api.js +41 -3
- package/build/src/api.js.map +1 -1
- package/build/src/binding-post.js +236 -182
- package/build/src/binding-post.js.map +1 -1
- package/build/src/binding-redirect.js +303 -215
- package/build/src/binding-redirect.js.map +1 -1
- package/build/src/binding-simplesign.js +285 -137
- package/build/src/binding-simplesign.js.map +1 -1
- package/build/src/entity-idp.js +130 -47
- package/build/src/entity-idp.js.map +1 -1
- package/build/src/entity-sp.js +81 -39
- package/build/src/entity-sp.js.map +1 -1
- package/build/src/entity.js +100 -62
- package/build/src/entity.js.map +1 -1
- package/build/src/extractor.js +118 -151
- package/build/src/extractor.js.map +1 -1
- package/build/src/flow.js +100 -96
- package/build/src/flow.js.map +1 -1
- package/build/src/libsaml.js +315 -259
- package/build/src/libsaml.js.map +1 -1
- package/build/src/metadata-idp.js +60 -30
- package/build/src/metadata-idp.js.map +1 -1
- package/build/src/metadata-sp.js +51 -41
- package/build/src/metadata-sp.js.map +1 -1
- package/build/src/metadata.js +47 -43
- package/build/src/metadata.js.map +1 -1
- package/build/src/options.js +73 -0
- package/build/src/options.js.map +1 -0
- package/build/src/urn.js +28 -1
- package/build/src/urn.js.map +1 -1
- package/build/src/utility.js +140 -85
- package/build/src/utility.js.map +1 -1
- package/build/src/validator.js +27 -10
- package/build/src/validator.js.map +1 -1
- package/package.json +16 -5
- package/types/src/api.d.ts +33 -3
- package/types/src/binding-post.d.ts +67 -34
- package/types/src/binding-redirect.d.ts +58 -31
- package/types/src/binding-simplesign.d.ts +77 -21
- package/types/src/entity-idp.d.ts +40 -31
- package/types/src/entity-sp.d.ts +37 -27
- package/types/src/entity.d.ts +71 -77
- package/types/src/extractor.d.ts +31 -22
- package/types/src/flow.d.ts +24 -2
- package/types/src/libsaml.d.ts +172 -118
- package/types/src/metadata-idp.d.ts +27 -11
- package/types/src/metadata-sp.d.ts +29 -19
- package/types/src/metadata.d.ts +59 -34
- package/types/src/options.d.ts +37 -0
- package/types/src/types.d.ts +250 -24
- package/types/src/urn.d.ts +7 -0
- package/types/src/utility.d.ts +139 -90
- package/types/src/validator.d.ts +21 -0
- package/.circleci/config.yml +0 -98
- package/.editorconfig +0 -19
- package/.github/FUNDING.yml +0 -1
- package/.github/workflows/deploy-docs.yml +0 -56
- package/.pre-commit.sh +0 -15
- package/.snyk +0 -4
- package/Makefile +0 -25
- package/index.ts +0 -28
- package/samlify-2.11.0.tgz +0 -0
- package/src/api.ts +0 -48
- package/src/binding-post.ts +0 -336
- package/src/binding-redirect.ts +0 -335
- package/src/binding-simplesign.ts +0 -231
- package/src/entity-idp.ts +0 -145
- package/src/entity-sp.ts +0 -114
- package/src/entity.ts +0 -243
- package/src/extractor.ts +0 -399
- package/src/flow.ts +0 -469
- package/src/libsaml.ts +0 -779
- package/src/metadata-idp.ts +0 -146
- package/src/metadata-sp.ts +0 -203
- package/src/metadata.ts +0 -166
- package/src/types.ts +0 -127
- package/src/urn.ts +0 -210
- package/src/utility.ts +0 -259
- package/src/validator.ts +0 -44
- package/tsconfig.json +0 -41
- package/tslint.json +0 -35
- package/types.d.ts +0 -2
- package/vitest.config.ts +0 -12
package/build/src/entity-idp.js
CHANGED
|
@@ -68,11 +68,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
68
68
|
exports.IdentityProvider = void 0;
|
|
69
69
|
exports.default = default_1;
|
|
70
70
|
/**
|
|
71
|
-
* @file entity-idp.ts
|
|
72
|
-
* @author tngan
|
|
73
|
-
* @desc
|
|
74
|
-
|
|
71
|
+
* @file entity-idp.ts
|
|
72
|
+
* @author tngan
|
|
73
|
+
* @desc Identity provider: builds login responses and parses inbound
|
|
74
|
+
* login requests coming from a service provider.
|
|
75
|
+
*/
|
|
75
76
|
var entity_1 = __importDefault(require("./entity"));
|
|
77
|
+
var options_1 = require("./options");
|
|
76
78
|
var libsaml_1 = __importDefault(require("./libsaml"));
|
|
77
79
|
var urn_1 = require("./urn");
|
|
78
80
|
var binding_post_1 = __importDefault(require("./binding-post"));
|
|
@@ -81,68 +83,149 @@ var binding_simplesign_1 = __importDefault(require("./binding-simplesign"));
|
|
|
81
83
|
var flow_1 = require("./flow");
|
|
82
84
|
var utility_1 = require("./utility");
|
|
83
85
|
/**
|
|
84
|
-
*
|
|
86
|
+
* Factory returning a new {@link IdentityProvider}. An IdP can be built
|
|
87
|
+
* from an XML metadata document or from a programmatic settings object.
|
|
88
|
+
*
|
|
89
|
+
* @param props IdP settings
|
|
85
90
|
*/
|
|
86
91
|
function default_1(props) {
|
|
87
92
|
return new IdentityProvider(props);
|
|
88
93
|
}
|
|
89
94
|
/**
|
|
90
|
-
*
|
|
95
|
+
* Swap the default `samlp:` / `saml:` prefixes inside an XML template
|
|
96
|
+
* with caller-supplied prefixes. Both the prefix occurrences and the
|
|
97
|
+
* `xmlns:` namespace bindings are rewritten so the resulting XML
|
|
98
|
+
* remains well-formed and namespace-correct (saml-core §1.4 — prefix
|
|
99
|
+
* choice is not normative).
|
|
91
100
|
*/
|
|
101
|
+
function applyTagPrefixes(xml, prefixes) {
|
|
102
|
+
var out = xml;
|
|
103
|
+
if (prefixes.protocol && prefixes.protocol !== 'samlp') {
|
|
104
|
+
var p = prefixes.protocol;
|
|
105
|
+
out = out
|
|
106
|
+
.replace(/<samlp:/g, "<".concat(p, ":"))
|
|
107
|
+
.replace(/<\/samlp:/g, "</".concat(p, ":"))
|
|
108
|
+
.replace(/xmlns:samlp="/g, "xmlns:".concat(p, "=\""));
|
|
109
|
+
}
|
|
110
|
+
if (prefixes.assertion && prefixes.assertion !== 'saml') {
|
|
111
|
+
var a = prefixes.assertion;
|
|
112
|
+
out = out
|
|
113
|
+
.replace(/<saml:/g, "<".concat(a, ":"))
|
|
114
|
+
.replace(/<\/saml:/g, "</".concat(a, ":"))
|
|
115
|
+
.replace(/xmlns:saml="/g, "xmlns:".concat(a, "=\""));
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
/** Identity-provider entity. */
|
|
92
120
|
var IdentityProvider = /** @class */ (function (_super) {
|
|
93
121
|
__extends(IdentityProvider, _super);
|
|
122
|
+
/**
|
|
123
|
+
* Build an IdP, expanding `loginResponseTemplate.attributes` into a
|
|
124
|
+
* pre-baked AttributeStatement template when supplied.
|
|
125
|
+
*/
|
|
94
126
|
function IdentityProvider(idpSetting) {
|
|
127
|
+
var _a, _b, _c;
|
|
95
128
|
var defaultIdpEntitySetting = {
|
|
96
129
|
wantAuthnRequestsSigned: false,
|
|
97
130
|
tagPrefix: {
|
|
98
131
|
encryptedAssertion: 'saml',
|
|
99
132
|
},
|
|
100
133
|
};
|
|
101
|
-
var entitySetting = Object.assign(defaultIdpEntitySetting, idpSetting);
|
|
102
|
-
//
|
|
134
|
+
var entitySetting = Object.assign({}, defaultIdpEntitySetting, idpSetting);
|
|
135
|
+
// Deep-merge tagPrefix so callers can override `protocol` / `assertion`
|
|
136
|
+
// without dropping the `encryptedAssertion: 'saml'` default that
|
|
137
|
+
// libsaml.encryptAssertion depends on (#388, saml-core §1.4).
|
|
138
|
+
entitySetting.tagPrefix = __assign(__assign({}, defaultIdpEntitySetting.tagPrefix), idpSetting.tagPrefix);
|
|
103
139
|
if (idpSetting.loginResponseTemplate) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
var
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
attributeTemplate = idpSetting.loginResponseTemplate.additionalTemplates.attributeTemplate;
|
|
118
|
-
}
|
|
119
|
-
var replacement = {
|
|
120
|
-
AttributeStatement: libsaml_1.default.attributeStatementBuilder(idpSetting.loginResponseTemplate.attributes, attributeTemplate, attributeStatementTemplate),
|
|
121
|
-
};
|
|
122
|
-
entitySetting.loginResponseTemplate = __assign(__assign({}, entitySetting.loginResponseTemplate), { context: libsaml_1.default.replaceTagsByValue(entitySetting.loginResponseTemplate.context, replacement) });
|
|
140
|
+
var template = idpSetting.loginResponseTemplate;
|
|
141
|
+
if ((0, utility_1.isString)(template.context) && Array.isArray(template.attributes)) {
|
|
142
|
+
var additional = template.additionalTemplates;
|
|
143
|
+
var attributeStatementTemplate = additional && additional.attributeStatementTemplate
|
|
144
|
+
? additional.attributeStatementTemplate
|
|
145
|
+
: libsaml_1.default.defaultAttributeStatementTemplate;
|
|
146
|
+
var attributeTemplate = additional && additional.attributeTemplate
|
|
147
|
+
? additional.attributeTemplate
|
|
148
|
+
: libsaml_1.default.defaultAttributeTemplate;
|
|
149
|
+
var attributeStatement = libsaml_1.default.attributeStatementBuilder(template.attributes, attributeTemplate, attributeStatementTemplate);
|
|
150
|
+
entitySetting.loginResponseTemplate = __assign(__assign({}, entitySetting.loginResponseTemplate), { context: entitySetting.loginResponseTemplate.context.replace('{AttributeStatement}', attributeStatement) });
|
|
123
151
|
}
|
|
124
152
|
else {
|
|
125
153
|
console.warn('Invalid login response template');
|
|
126
154
|
}
|
|
127
155
|
}
|
|
156
|
+
// saml-core §1.4 — XML namespace prefixes are not normative; only the
|
|
157
|
+
// URI bindings are. When the caller overrides `tagPrefix.protocol` or
|
|
158
|
+
// `tagPrefix.assertion`, rewrite both the caller's templates and the
|
|
159
|
+
// built-in defaults so the bindings emit the rebound prefixes
|
|
160
|
+
// downstream (closes #388). The rewritten defaults land on a separate
|
|
161
|
+
// `tagPrefixedDefaults` slot so users that only set
|
|
162
|
+
// `loginResponseTemplate` (without `tagPrefix`) continue to follow the
|
|
163
|
+
// legacy binding fallback path.
|
|
164
|
+
var tp = entitySetting.tagPrefix;
|
|
165
|
+
var protocolPrefix = tp === null || tp === void 0 ? void 0 : tp.protocol;
|
|
166
|
+
var assertionPrefix = tp === null || tp === void 0 ? void 0 : tp.assertion;
|
|
167
|
+
var overridesProtocol = !!protocolPrefix && protocolPrefix !== 'samlp';
|
|
168
|
+
var overridesAssertion = !!assertionPrefix && assertionPrefix !== 'saml';
|
|
169
|
+
if (overridesProtocol || overridesAssertion) {
|
|
170
|
+
var prefixes = { protocol: protocolPrefix, assertion: assertionPrefix };
|
|
171
|
+
// Rewrite any caller-supplied templates in place so customTagReplacement
|
|
172
|
+
// consumers see the rebound prefixes too.
|
|
173
|
+
var callerLoginCtx = (_a = entitySetting.loginResponseTemplate) === null || _a === void 0 ? void 0 : _a.context;
|
|
174
|
+
if ((0, utility_1.isString)(callerLoginCtx)) {
|
|
175
|
+
entitySetting.loginResponseTemplate = __assign(__assign({}, entitySetting.loginResponseTemplate), { context: applyTagPrefixes(callerLoginCtx, prefixes) });
|
|
176
|
+
}
|
|
177
|
+
var callerLogoutReqCtx = (_b = entitySetting.logoutRequestTemplate) === null || _b === void 0 ? void 0 : _b.context;
|
|
178
|
+
if ((0, utility_1.isString)(callerLogoutReqCtx)) {
|
|
179
|
+
entitySetting.logoutRequestTemplate = __assign(__assign({}, entitySetting.logoutRequestTemplate), { context: applyTagPrefixes(callerLogoutReqCtx, prefixes) });
|
|
180
|
+
}
|
|
181
|
+
var callerLogoutRespCtx = (_c = entitySetting.logoutResponseTemplate) === null || _c === void 0 ? void 0 : _c.context;
|
|
182
|
+
if ((0, utility_1.isString)(callerLogoutRespCtx)) {
|
|
183
|
+
entitySetting.logoutResponseTemplate = __assign(__assign({}, entitySetting.logoutResponseTemplate), { context: applyTagPrefixes(callerLogoutRespCtx, prefixes) });
|
|
184
|
+
}
|
|
185
|
+
// Pre-rewrite copies of the default templates so the bindings emit
|
|
186
|
+
// rebound prefixes when no caller template is supplied.
|
|
187
|
+
entitySetting.tagPrefixedDefaults = {
|
|
188
|
+
loginResponseTemplate: {
|
|
189
|
+
context: applyTagPrefixes(libsaml_1.default.defaultLoginResponseTemplate.context, prefixes),
|
|
190
|
+
},
|
|
191
|
+
logoutRequestTemplate: {
|
|
192
|
+
context: applyTagPrefixes(libsaml_1.default.defaultLogoutRequestTemplate.context, prefixes),
|
|
193
|
+
},
|
|
194
|
+
logoutResponseTemplate: {
|
|
195
|
+
context: applyTagPrefixes(libsaml_1.default.defaultLogoutResponseTemplate.context, prefixes),
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
}
|
|
128
199
|
return _super.call(this, entitySetting, 'idp') || this;
|
|
129
200
|
}
|
|
130
201
|
/**
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
202
|
+
* Build a login response for delivery to the supplied service provider.
|
|
203
|
+
*
|
|
204
|
+
* The fifth parameter accepts either a callback (legacy positional shape)
|
|
205
|
+
* or an options bag `{ relayState?, customTagReplacement?, encryptThenSign? }`.
|
|
206
|
+
* When the legacy shape is used, the trailing `legacyEncryptThenSign` and
|
|
207
|
+
* `legacyRelayState` positional arguments are honoured. Per
|
|
208
|
+
* `saml-bindings §3.4.3 / §3.5.3`, RelayState is request-scoped — pass it
|
|
209
|
+
* via the options bag instead of `entitySetting.relayState`.
|
|
210
|
+
*
|
|
211
|
+
* @param sp target service provider
|
|
212
|
+
* @param requestInfo parsed request used to set `InResponseTo`
|
|
213
|
+
* @param binding `post`, `simpleSign`, or `redirect`
|
|
214
|
+
* @param user authenticated user
|
|
215
|
+
* @param optionsOrCallback per-request options or legacy custom-template callback
|
|
216
|
+
* @param legacyEncryptThenSign legacy positional `encryptThenSign`; ignored when options bag is used
|
|
217
|
+
* @param legacyRelayState legacy positional `relayState`; ignored when options bag is used
|
|
218
|
+
*/
|
|
219
|
+
IdentityProvider.prototype.createLoginResponse = function (sp, requestInfo, binding, user, optionsOrCallback, legacyEncryptThenSign, legacyRelayState) {
|
|
141
220
|
return __awaiter(this, void 0, void 0, function () {
|
|
142
|
-
var protocol, context, _a;
|
|
221
|
+
var opts, customTagReplacement, encryptThenSign, relayState, protocol, context, _a;
|
|
143
222
|
return __generator(this, function (_b) {
|
|
144
223
|
switch (_b.label) {
|
|
145
224
|
case 0:
|
|
225
|
+
opts = (0, options_1.normalizeCreateLoginResponseOptions)(optionsOrCallback, legacyEncryptThenSign, legacyRelayState);
|
|
226
|
+
customTagReplacement = opts.customTagReplacement;
|
|
227
|
+
encryptThenSign = opts.encryptThenSign;
|
|
228
|
+
relayState = opts.relayState;
|
|
146
229
|
protocol = urn_1.namespace.binding[binding];
|
|
147
230
|
context = null;
|
|
148
231
|
_a = protocol;
|
|
@@ -164,7 +247,7 @@ var IdentityProvider = /** @class */ (function (_super) {
|
|
|
164
247
|
sp: sp,
|
|
165
248
|
}, user, relayState, customTagReplacement)];
|
|
166
249
|
case 4:
|
|
167
|
-
context = _b.sent();
|
|
250
|
+
context = (_b.sent());
|
|
168
251
|
return [3 /*break*/, 7];
|
|
169
252
|
case 5: return [2 /*return*/, binding_redirect_1.default.loginResponseRedirectURL(requestInfo, {
|
|
170
253
|
idp: this,
|
|
@@ -177,21 +260,21 @@ var IdentityProvider = /** @class */ (function (_super) {
|
|
|
177
260
|
});
|
|
178
261
|
};
|
|
179
262
|
/**
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
* @param
|
|
183
|
-
* @param
|
|
263
|
+
* Parse, validate and verify an inbound login request.
|
|
264
|
+
*
|
|
265
|
+
* @param sp service provider that produced the request
|
|
266
|
+
* @param binding `redirect`, `post`, or `simpleSign`
|
|
267
|
+
* @param req HTTP request envelope
|
|
184
268
|
*/
|
|
185
269
|
IdentityProvider.prototype.parseLoginRequest = function (sp, binding, req) {
|
|
186
|
-
var self = this;
|
|
187
270
|
return (0, flow_1.flow)({
|
|
188
271
|
from: sp,
|
|
189
|
-
self:
|
|
190
|
-
checkSignature:
|
|
272
|
+
self: this,
|
|
273
|
+
checkSignature: this.entityMeta.isWantAuthnRequestsSigned(),
|
|
191
274
|
parserType: 'SAMLRequest',
|
|
192
275
|
type: 'login',
|
|
193
276
|
binding: binding,
|
|
194
|
-
request: req
|
|
277
|
+
request: req,
|
|
195
278
|
});
|
|
196
279
|
};
|
|
197
280
|
return IdentityProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-idp.js","sourceRoot":"","sources":["../../src/entity-idp.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"entity-idp.js","sourceRoot":"","sources":["../../src/entity-idp.ts"],"names":[],"mappings":"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"}
|
package/build/src/entity-sp.js
CHANGED
|
@@ -32,87 +32,129 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
32
32
|
exports.ServiceProvider = void 0;
|
|
33
33
|
exports.default = default_1;
|
|
34
34
|
/**
|
|
35
|
-
* @file entity-sp.ts
|
|
36
|
-
* @author tngan
|
|
37
|
-
* @desc
|
|
38
|
-
|
|
35
|
+
* @file entity-sp.ts
|
|
36
|
+
* @author tngan
|
|
37
|
+
* @desc Service provider: builds login requests and parses inbound login
|
|
38
|
+
* responses coming from an identity provider.
|
|
39
|
+
*/
|
|
39
40
|
var entity_1 = __importDefault(require("./entity"));
|
|
41
|
+
var options_1 = require("./options");
|
|
40
42
|
var urn_1 = require("./urn");
|
|
41
43
|
var binding_redirect_1 = __importDefault(require("./binding-redirect"));
|
|
42
44
|
var binding_post_1 = __importDefault(require("./binding-post"));
|
|
43
45
|
var binding_simplesign_1 = __importDefault(require("./binding-simplesign"));
|
|
44
46
|
var flow_1 = require("./flow");
|
|
45
|
-
|
|
46
|
-
* @
|
|
47
|
+
/**
|
|
48
|
+
* Factory returning a new {@link ServiceProvider}. An SP can be built from
|
|
49
|
+
* an XML metadata document or from a programmatic settings object.
|
|
50
|
+
*
|
|
51
|
+
* @param props SP settings
|
|
47
52
|
*/
|
|
48
53
|
function default_1(props) {
|
|
49
54
|
return new ServiceProvider(props);
|
|
50
55
|
}
|
|
51
|
-
/**
|
|
52
|
-
* @desc Service provider can be configured using either metadata importing or spSetting
|
|
53
|
-
* @param {object} spSettingimport { FlowResult } from '../types/src/flow.d';
|
|
54
|
-
|
|
55
|
-
*/
|
|
56
|
+
/** Service-provider entity. */
|
|
56
57
|
var ServiceProvider = /** @class */ (function (_super) {
|
|
57
58
|
__extends(ServiceProvider, _super);
|
|
58
59
|
/**
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
* Build an SP with sensible defaults for signing flags.
|
|
61
|
+
*
|
|
62
|
+
* @param spSetting SP settings object
|
|
63
|
+
*/
|
|
62
64
|
function ServiceProvider(spSetting) {
|
|
63
65
|
var entitySetting = Object.assign({
|
|
64
66
|
authnRequestsSigned: false,
|
|
65
67
|
wantAssertionsSigned: false,
|
|
66
68
|
wantMessageSigned: false,
|
|
67
69
|
}, spSetting);
|
|
70
|
+
if (entitySetting.wantMessageSigned && entitySetting.signatureConfig === undefined) {
|
|
71
|
+
// saml-bindings §3.5 — default signature placement when the SP wants
|
|
72
|
+
// a signed message but didn't declare where. Matches the fallback the
|
|
73
|
+
// binding builders already use at sign time, so downstream consumers
|
|
74
|
+
// (e.g. `getEntitySetting().signatureConfig`) see a populated value
|
|
75
|
+
// for already-working configurations instead of `undefined`.
|
|
76
|
+
entitySetting.signatureConfig = {
|
|
77
|
+
prefix: 'ds',
|
|
78
|
+
location: {
|
|
79
|
+
reference: "/*[local-name(.)='Response']/*[local-name(.)='Issuer']",
|
|
80
|
+
action: 'after',
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
68
84
|
return _super.call(this, entitySetting, 'sp') || this;
|
|
69
85
|
}
|
|
70
86
|
/**
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
87
|
+
* Build a login request targeting the supplied identity provider.
|
|
88
|
+
*
|
|
89
|
+
* The third parameter accepts either a callback (legacy shape) or an
|
|
90
|
+
* options bag `{ relayState?, customTagReplacement? }`. Per
|
|
91
|
+
* `saml-bindings §3.4.3 / §3.5.3`, RelayState is request-scoped — pass
|
|
92
|
+
* it via the options bag instead of `entitySetting.relayState`.
|
|
93
|
+
*
|
|
94
|
+
* @param idp target identity provider
|
|
95
|
+
* @param binding `redirect` (default), `post`, or `simpleSign`
|
|
96
|
+
* @param optionsOrCallback per-request options or a custom-template callback
|
|
97
|
+
*/
|
|
98
|
+
ServiceProvider.prototype.createLoginRequest = function (idp, binding, optionsOrCallback) {
|
|
99
|
+
var _a;
|
|
100
|
+
var opts = (0, options_1.normalizeCreateLoginRequestOptions)(optionsOrCallback);
|
|
101
|
+
var customTagReplacement = opts.customTagReplacement;
|
|
102
|
+
var requestRelayState = (_a = opts.relayState) !== null && _a !== void 0 ? _a : this.entitySetting.relayState;
|
|
103
|
+
// saml-core §3.4.1 — `ForceAuthn` is a per-request boolean flag; when
|
|
104
|
+
// true the IdP MUST re-authenticate the user instead of relying on a
|
|
105
|
+
// previous security context (saml-profiles §4.1.4.1).
|
|
106
|
+
var forceAuthn = opts.forceAuthn;
|
|
107
|
+
// saml-core §3.4.1 — `AssertionConsumerServiceIndex` is mutually
|
|
108
|
+
// exclusive with `AssertionConsumerServiceURL` / `ProtocolBinding`.
|
|
109
|
+
// When set, the binding builders omit both of those attributes so the
|
|
110
|
+
// request only references the metadata-declared endpoint by index
|
|
111
|
+
// (saml-profiles §4.1.4.1).
|
|
112
|
+
var assertionConsumerServiceIndex = opts.assertionConsumerServiceIndex;
|
|
113
|
+
var selectedBinding = binding !== null && binding !== void 0 ? binding : 'redirect';
|
|
78
114
|
var nsBinding = urn_1.namespace.binding;
|
|
79
|
-
var protocol = nsBinding[
|
|
80
|
-
|
|
81
|
-
|
|
115
|
+
var protocol = nsBinding[selectedBinding];
|
|
116
|
+
// saml-core §3.4.1 / saml-metadata §2.4.4: the SP's `AuthnRequestsSigned`
|
|
117
|
+
// attribute and the IdP's `WantAuthnRequestsSigned` attribute must agree;
|
|
118
|
+
// surface both observed values so the operator can tell which side is
|
|
119
|
+
// misconfigured. The error code stays first so prefix-based handlers
|
|
120
|
+
// (per saml-conformance §3) keep working.
|
|
121
|
+
var spSigned = this.entityMeta.isAuthnRequestSigned();
|
|
122
|
+
var idpWants = idp.entityMeta.isWantAuthnRequestsSigned();
|
|
123
|
+
if (spSigned !== idpWants) {
|
|
124
|
+
throw new Error("ERR_METADATA_CONFLICT_REQUEST_SIGNED_FLAG: SP AuthnRequestsSigned=".concat(spSigned, " but IdP WantAuthnRequestsSigned=").concat(idpWants));
|
|
82
125
|
}
|
|
83
126
|
var context = null;
|
|
84
127
|
switch (protocol) {
|
|
85
128
|
case nsBinding.redirect:
|
|
86
|
-
return binding_redirect_1.default.loginRequestRedirectURL({ idp: idp, sp: this }, customTagReplacement);
|
|
129
|
+
return binding_redirect_1.default.loginRequestRedirectURL({ idp: idp, sp: this }, customTagReplacement, requestRelayState, forceAuthn, assertionConsumerServiceIndex);
|
|
87
130
|
case nsBinding.post:
|
|
88
|
-
context = binding_post_1.default.base64LoginRequest("/*[local-name(.)='AuthnRequest']", { idp: idp, sp: this }, customTagReplacement);
|
|
131
|
+
context = binding_post_1.default.base64LoginRequest("/*[local-name(.)='AuthnRequest']", { idp: idp, sp: this }, customTagReplacement, forceAuthn, assertionConsumerServiceIndex);
|
|
89
132
|
break;
|
|
90
133
|
case nsBinding.simpleSign:
|
|
91
|
-
|
|
92
|
-
context = binding_simplesign_1.default.base64LoginRequest({ idp: idp, sp: this }, customTagReplacement);
|
|
134
|
+
context = binding_simplesign_1.default.base64LoginRequest({ idp: idp, sp: this }, customTagReplacement, requestRelayState, forceAuthn, assertionConsumerServiceIndex);
|
|
93
135
|
break;
|
|
94
136
|
default:
|
|
95
|
-
// Will support artifact in the next release
|
|
96
137
|
throw new Error('ERR_SP_LOGIN_REQUEST_UNDEFINED_BINDING');
|
|
97
138
|
}
|
|
98
|
-
return __assign(__assign({}, context), { relayState:
|
|
139
|
+
return __assign(__assign({}, context), { relayState: requestRelayState, entityEndpoint: idp.entityMeta.getSingleSignOnService(selectedBinding), type: 'SAMLRequest' });
|
|
99
140
|
};
|
|
100
141
|
/**
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
142
|
+
* Parse, validate and verify an inbound login response.
|
|
143
|
+
*
|
|
144
|
+
* @param idp identity provider that produced the response
|
|
145
|
+
* @param binding `redirect`, `post`, or `simpleSign`
|
|
146
|
+
* @param request HTTP request envelope
|
|
147
|
+
*/
|
|
106
148
|
ServiceProvider.prototype.parseLoginResponse = function (idp, binding, request) {
|
|
107
|
-
var self = this;
|
|
108
149
|
return (0, flow_1.flow)({
|
|
109
150
|
from: idp,
|
|
110
|
-
self:
|
|
111
|
-
|
|
151
|
+
self: this,
|
|
152
|
+
// SAML response is always required to be signed.
|
|
153
|
+
checkSignature: true,
|
|
112
154
|
parserType: 'SAMLResponse',
|
|
113
155
|
type: 'login',
|
|
114
156
|
binding: binding,
|
|
115
|
-
request: request
|
|
157
|
+
request: request,
|
|
116
158
|
});
|
|
117
159
|
};
|
|
118
160
|
return ServiceProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-sp.js","sourceRoot":"","sources":["../../src/entity-sp.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"entity-sp.js","sourceRoot":"","sources":["../../src/entity-sp.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,4BAEC;AAjCD;;;;;GAKG;AACH,oDAA8B;AAY9B,qCAA+D;AAC/D,6BAAkC;AAClC,wEAAiD;AACjD,gEAAyC;AACzC,4EAAqD;AACrD,+BAA8B;AAE9B;;;;;GAKG;AACH,mBAAyB,KAA8B;IACrD,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,+BAA+B;AAC/B;IAAqC,mCAAM;IAGzC;;;;OAIG;IACH,yBAAY,SAAkC;QAC5C,IAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;YAClC,mBAAmB,EAAE,KAAK;YAC1B,oBAAoB,EAAE,KAAK;YAC3B,iBAAiB,EAAE,KAAK;SACzB,EAAE,SAAS,CAAC,CAAC;QACd,IAAI,aAAa,CAAC,iBAAiB,IAAI,aAAa,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACnF,qEAAqE;YACrE,sEAAsE;YACtE,qEAAqE;YACrE,oEAAoE;YACpE,6DAA6D;YAC7D,aAAa,CAAC,eAAe,GAAG;gBAC9B,MAAM,EAAE,IAAI;gBACZ,QAAQ,EAAE;oBACR,SAAS,EAAE,wDAAwD;oBACnE,MAAM,EAAE,OAAO;iBAChB;aACF,CAAC;QACJ,CAAC;QACD,OAAA,MAAK,YAAC,aAAa,EAAE,IAAI,CAAC,SAAC;IAC7B,CAAC;IAED;;;;;;;;;;;OAWG;IACI,4CAAkB,GAAzB,UACE,GAAqB,EACrB,OAAgB,EAChB,iBAAoE;;QAEpE,IAAM,IAAI,GAAG,IAAA,4CAAkC,EAAC,iBAAiB,CAAC,CAAC;QACnE,IAAM,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAC;QACvD,IAAM,iBAAiB,GAAG,MAAA,IAAI,CAAC,UAAU,mCAAI,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC;QAC3E,sEAAsE;QACtE,qEAAqE;QACrE,sDAAsD;QACtD,IAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,iEAAiE;QACjE,oEAAoE;QACpE,sEAAsE;QACtE,kEAAkE;QAClE,4BAA4B;QAC5B,IAAM,6BAA6B,GAAG,IAAI,CAAC,6BAA6B,CAAC;QACzE,IAAM,eAAe,GAAG,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,UAAU,CAAC;QAE9C,IAAM,SAAS,GAAG,eAAS,CAAC,OAAO,CAAC;QACpC,IAAM,QAAQ,GAAG,SAAS,CAAC,eAAe,CAAC,CAAC;QAC5C,0EAA0E;QAC1E,0EAA0E;QAC1E,sEAAsE;QACtE,qEAAqE;QACrE,0CAA0C;QAC1C,IAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC;QACxD,IAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,yBAAyB,EAAE,CAAC;QAC5D,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,4EAAqE,QAAQ,8CAAoC,QAAQ,CAAE,CAC5H,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,GAAqD,IAAI,CAAC;QACrE,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,SAAS,CAAC,QAAQ;gBACrB,OAAO,0BAAe,CAAC,uBAAuB,CAC5C,EAAE,GAAG,KAAA,EAAE,EAAE,EAAE,IAAI,EAAE,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,EACV,6BAA6B,CAC9B,CAAC;YAEJ,KAAK,SAAS,CAAC,IAAI;gBACjB,OAAO,GAAG,sBAAW,CAAC,kBAAkB,CACtC,kCAAkC,EAClC,EAAE,GAAG,KAAA,EAAE,EAAE,EAAE,IAAI,EAAE,EACjB,oBAAoB,EACpB,UAAU,EACV,6BAA6B,CAC9B,CAAC;gBACF,MAAM;YAER,KAAK,SAAS,CAAC,UAAU;gBACvB,OAAO,GAAG,4BAAiB,CAAC,kBAAkB,CAC5C,EAAE,GAAG,KAAA,EAAE,EAAE,EAAE,IAAI,EAAE,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,EACV,6BAA6B,CACF,CAAC;gBAC9B,MAAM;YAER;gBACE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC9D,CAAC;QAED,6BACK,OAAO,KACV,UAAU,EAAE,iBAAiB,EAC7B,cAAc,EAAE,GAAG,CAAC,UAAU,CAAC,sBAAsB,CAAC,eAAe,CAAW,EAChF,IAAI,EAAE,aAAa,IACnB;IACJ,CAAC;IAED;;;;;;OAMG;IACI,4CAAkB,GAAzB,UAA0B,GAAqB,EAAE,OAAe,EAAE,OAAyB;QACzF,OAAO,IAAA,WAAI,EAAC;YACV,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,IAAI;YACV,iDAAiD;YACjD,cAAc,EAAE,IAAI;YACpB,UAAU,EAAE,cAAc;YAC1B,IAAI,EAAE,OAAO;YACb,OAAO,SAAA;YACP,OAAO,SAAA;SACR,CAAC,CAAC;IACL,CAAC;IACH,sBAAC;AAAD,CAAC,AA5ID,CAAqC,gBAAM,GA4I1C;AA5IY,0CAAe"}
|