scimgateway 4.1.10 → 4.1.12
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 +22 -7
- package/lib/scimgateway.js +9 -9
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -17,12 +17,12 @@ Validated through IdP's:
|
|
|
17
17
|
Latest news:
|
|
18
18
|
|
|
19
19
|
- **BREAKING**: [SCIM Stream](https://elshaug.xyz/docs/scim-stream) is the modern way of user provisioning letting clients subscribe to messages instead of traditional IGA top-down provisioning. SCIM Stream includes **SCIM Stream Gateway**, the next generation SCIM Gateway that supports message subscription and automated provisioning
|
|
20
|
-
-
|
|
20
|
+
- Supports OAuth Client Credentials authentication
|
|
21
21
|
- Major version v4.0.0. getUsers() and getGroups() replacing some deprecated methods. No limitations on filtering/sorting. Admin user access can be linked to specific baseEntities. New MongoDB plugin
|
|
22
22
|
- ipAllowList for restricting access to allowlisted IP addresses or subnets e.g. Azure AD IP-range
|
|
23
23
|
- General LDAP plugin configured for Active Directory
|
|
24
24
|
- [PlugSSO](https://elshaug.xyz/docs/plugsso) using SCIM Gateway
|
|
25
|
-
-
|
|
25
|
+
- Each authentication configuration allowing more than one admin user including option for readOnly
|
|
26
26
|
- Codebase moved from callback of h... to the the promise(d) land of async/await
|
|
27
27
|
- Supports configuration by environments and external files
|
|
28
28
|
- Health monitoring through "/ping" URL, and option for error notifications by email
|
|
@@ -379,11 +379,11 @@ Definitions in `endpoint` object are customized according to our plugin code. Pl
|
|
|
379
379
|
|
|
380
380
|
Note, we should normally use certificate (https) for communicating with SCIM Gateway unless we install ScimGatway locally on the manager (e.g. on the CA Connector Server). When installed on the manager, we could use `http://localhost:port` or `http://127.0.0.1:port` which will not be passed down to the data link layer for transmission. We could then also set {"localhostonly": true}
|
|
381
381
|
|
|
382
|
-
- **ipAllowList** - Array of one or more IPv4/IPv6 subnets (CIDR) allowed for incoming traffic. E.g. using Azure AD as IdP, we would like to restrict access to IP addresses used by Azure AD. Azure IP-range can be downloaded from: [https://azureipranges.azurewebsites.net](https://azureipranges.azurewebsites.net), enter **AzureActiveDirectory** in the search list and select JSON download. Copy the "addressPrefixes" array content and paste into ipAllowList array. CIDR single IP-host syntax is a.b.c.d/32. Note, front-end HTTP proxy or a load balancer must include **X-Forwarded-For** header. Configuration example:
|
|
382
|
+
- **ipAllowList** - Array of one or more IPv4/IPv6 subnets (CIDR) allowed for incoming traffic. E.g. using Azure AD as IdP, we would like to restrict access to IP addresses used by Azure AD. Azure IP-range can be downloaded from: [https://azureipranges.azurewebsites.net](https://azureipranges.azurewebsites.net), enter **AzureActiveDirectory** in the search list and select JSON download. Copy the "addressPrefixes" array content and paste into ipAllowList array. CIDR single IP-host syntax is a.b.c.d/32. Note, front-end HTTP proxy or a load balancer must include client IP-address in the **X-Forwarded-For** header. Configuration example:
|
|
383
383
|
|
|
384
384
|
"ipAllowList": [
|
|
385
|
-
"13.
|
|
386
|
-
"13.66.
|
|
385
|
+
"13.64.151.161/32",
|
|
386
|
+
"13.66.141.64/27",
|
|
387
387
|
...
|
|
388
388
|
"2603:1056:2000::/48",
|
|
389
389
|
"2603:1057:2::/48"
|
|
@@ -1146,6 +1146,18 @@ MIT © [Jarle Elshaug](https://www.elshaug.xyz)
|
|
|
1146
1146
|
|
|
1147
1147
|
## Change log
|
|
1148
1148
|
|
|
1149
|
+
### v4.1.12
|
|
1150
|
+
|
|
1151
|
+
[Added]
|
|
1152
|
+
|
|
1153
|
+
- Dependencies bump
|
|
1154
|
+
|
|
1155
|
+
### v4.1.11
|
|
1156
|
+
|
|
1157
|
+
[Fixed]
|
|
1158
|
+
|
|
1159
|
+
- basic auth logon dialog should not show up when not configured
|
|
1160
|
+
|
|
1149
1161
|
### v4.1.10
|
|
1150
1162
|
|
|
1151
1163
|
[Added]
|
|
@@ -1181,13 +1193,16 @@ MIT © [Jarle Elshaug](https://www.elshaug.xyz)
|
|
|
1181
1193
|
- Symantec/Broadcom/CA ConnectorXpress configuration file `config\resources\Azure - ScimGateway.xml` for defining the Azure endpoint, have been updated with some new attributes according to plugin-azure-ad.json attribute mappings
|
|
1182
1194
|
|
|
1183
1195
|
### v4.1.6
|
|
1184
|
-
|
|
1196
|
+
|
|
1197
|
+
[Added]
|
|
1198
|
+
|
|
1185
1199
|
- Dependencies bump
|
|
1186
1200
|
|
|
1187
1201
|
### v4.1.5
|
|
1202
|
+
|
|
1188
1203
|
[Added]
|
|
1189
1204
|
|
|
1190
|
-
|
|
1205
|
+
SCIM Gateway related news:
|
|
1191
1206
|
|
|
1192
1207
|
- [SCIM Stream](https://elshaug.xyz/docs/scim-stream) is the modern way of user provisioning letting clients subscribe to messages instead of traditional IGA top-down provisioning. SCIM Stream includes **SCIM Stream Gateway**, the next generation SCIM Gateway that supports message subscription and automated provisioning
|
|
1193
1208
|
|
package/lib/scimgateway.js
CHANGED
|
@@ -123,7 +123,7 @@ const ScimGateway = function () {
|
|
|
123
123
|
logger.error(`${gwName}[${pluginName}] getPassword error: ${err.message}`)
|
|
124
124
|
throw err // above logger.error included because this unhanledExcepton will be handled by winston and may fail with an other internal winston error e.g. related to memoryUsage collection logic when running in unikernel
|
|
125
125
|
}
|
|
126
|
-
if (arr[i].password) foundBasic = true
|
|
126
|
+
if (arr[i].username && arr[i].password) foundBasic = true
|
|
127
127
|
}
|
|
128
128
|
if (!foundBasic) config.auth.basic = []
|
|
129
129
|
}
|
|
@@ -223,7 +223,7 @@ const ScimGateway = function () {
|
|
|
223
223
|
if (config.certificate.pfx.password) pwPfxPassword = ScimGateway.prototype.getPassword('scimgateway.certificate.pfx.password', configFile)
|
|
224
224
|
if (config.emailOnError.smtp.password) config.emailOnError.smtp.password = ScimGateway.prototype.getPassword('scimgateway.emailOnError.smtp.password', configFile)
|
|
225
225
|
|
|
226
|
-
if (!foundBasic && !foundBearerToken && !foundBearerJwtAzure && !foundBearerJwt) {
|
|
226
|
+
if (!foundBasic && !foundBearerToken && !foundBearerJwtAzure && !foundBearerJwt && !foundBearerOAuth) {
|
|
227
227
|
logger.error(`${gwName}[${pluginName}] Scimgateway password decryption failed or no password defined`)
|
|
228
228
|
logger.error(`${gwName}[${pluginName}] stopping...\n`)
|
|
229
229
|
throw (new Error('Using exception to stop further asynchronous code execution (ensure synchronous logger flush to logfile and exit program), please ignore this one...'))
|
|
@@ -450,9 +450,9 @@ const ScimGateway = function () {
|
|
|
450
450
|
if (tokenObj.readOnly === true && method !== 'GET') return reject(new Error('only allowing readOnly for this bearerOAuth according to bearerOAuth configuration readOnly=true'))
|
|
451
451
|
return resolve(true)
|
|
452
452
|
} else {
|
|
453
|
-
for (let i = 0; i < arr.length; i++) { // resolve if token memory store have been cleared
|
|
454
|
-
if (utils.getEncrypted(authToken, arr[i].client_secret) ===
|
|
455
|
-
arr[i].isTokenRequested = true // flagged as true to not allow repeated resolvements
|
|
453
|
+
for (let i = 0; i < arr.length; i++) { // resolve if token memory store have been cleared because of a gateway restart
|
|
454
|
+
if (utils.getEncrypted(authToken, arr[i].client_secret) === arr[i].client_secret && !arr[i].isTokenRequested) {
|
|
455
|
+
arr[i].isTokenRequested = true // flagged as true to not allow repeated resolvements because token will also be cleared when expired
|
|
456
456
|
const baseEntities = utils.copyObj(arr[i].baseEntities)
|
|
457
457
|
let expires
|
|
458
458
|
let readOnly = false
|
|
@@ -505,7 +505,7 @@ const ScimGateway = function () {
|
|
|
505
505
|
logger.debug(`${gwName}[${pluginName}] request jwt.decode(authToken) = ${JSON.stringify(jwt.decode(authToken))}`)
|
|
506
506
|
}
|
|
507
507
|
if (authType === 'Bearer') ctx.set('WWW-Authenticate', 'Bearer realm=""')
|
|
508
|
-
else ctx.set('WWW-Authenticate', 'Basic realm=""')
|
|
508
|
+
else if (foundBasic) ctx.set('WWW-Authenticate', 'Basic realm=""')
|
|
509
509
|
ctx.set('Content-Type', 'application/json; charset=utf-8')
|
|
510
510
|
ctx.status = 401
|
|
511
511
|
ctx.body = { error: 'Access denied' }
|
|
@@ -658,7 +658,7 @@ const ScimGateway = function () {
|
|
|
658
658
|
for (let i = 0; i < arr.length; i++) {
|
|
659
659
|
if (!arr[i].client_id || !arr[i].client_secret) continue
|
|
660
660
|
if (arr[i].client_id === jsonBody.client_id && arr[i].client_secret === jsonBody.client_secret) { // authentication OK
|
|
661
|
-
token = utils.getEncrypted(
|
|
661
|
+
token = utils.getEncrypted(jsonBody.client_secret, jsonBody.client_secret)
|
|
662
662
|
baseEntities = utils.copyObj(arr[i].baseEntities)
|
|
663
663
|
if (arr[i].readOnly && arr[i].readOnly === true) readOnly = true
|
|
664
664
|
if (arr[i].expires_in && !isNaN(arr[i].expires_in)) expires = arr[i].expires_in
|
|
@@ -1327,7 +1327,7 @@ const ScimGateway = function () {
|
|
|
1327
1327
|
else { // try to get current groups the standard way
|
|
1328
1328
|
let res
|
|
1329
1329
|
try {
|
|
1330
|
-
res = await this[handler.groups.getMethod](ctx.params.baseEntity, { attribute: 'members.value', operator: 'eq', value: decodeURIComponent(id) }, ['
|
|
1330
|
+
res = await this[handler.groups.getMethod](ctx.params.baseEntity, { attribute: 'members.value', operator: 'eq', value: decodeURIComponent(id) }, ['id', 'displayName'])
|
|
1331
1331
|
} catch (err) {} // method may be implemented but throwing error like groups not supported/implemented
|
|
1332
1332
|
currentGroups = []
|
|
1333
1333
|
if (res && res.Resources && Array.isArray(res.Resources) && res.Resources.length > 0) {
|
|
@@ -1421,7 +1421,7 @@ const ScimGateway = function () {
|
|
|
1421
1421
|
// include groups
|
|
1422
1422
|
if (handle.getMethod === handler.users.getMethod && typeof this[handler.groups.getMethod] === 'function') {
|
|
1423
1423
|
logger.debug(`${gwName}[${pluginName}] calling "${handler.groups.getMethod}" and awaiting result`)
|
|
1424
|
-
const res = await this[handler.groups.getMethod](ctx.params.baseEntity, { attribute: 'members.value', operator: 'eq', value: id }, ['
|
|
1424
|
+
const res = await this[handler.groups.getMethod](ctx.params.baseEntity, { attribute: 'members.value', operator: 'eq', value: id }, ['id', 'displayName'])
|
|
1425
1425
|
let grps = []
|
|
1426
1426
|
if (res && res.Resources && Array.isArray(res.Resources)) grps = res.Resources
|
|
1427
1427
|
else if (Array.isArray(res)) grps = res
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scimgateway",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.12",
|
|
4
4
|
"description": "Using SCIM protocol as a gateway for user provisioning to other endpoints",
|
|
5
5
|
"author": "Jarle Elshaug <jarle.elshaug@gmail.com> (https://elshaug.xyz)",
|
|
6
6
|
"homepage": "https://elshaug.xyz",
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
"https-proxy-agent": "^5.0.1",
|
|
38
38
|
"is-in-subnet": "^4.0.1",
|
|
39
39
|
"jsonwebtoken": "^8.5.1",
|
|
40
|
-
"koa": "^2.
|
|
40
|
+
"koa": "^2.14.0",
|
|
41
41
|
"koa-bodyparser": "^4.3.0",
|
|
42
42
|
"koa-router": "^12.0.0",
|
|
43
43
|
"ldapjs": "^2.3.3",
|
|
44
44
|
"lokijs": "^1.5.12",
|
|
45
|
-
"mongodb": "^4.
|
|
45
|
+
"mongodb": "^4.12.1",
|
|
46
46
|
"node-machine-id": "1.1.9",
|
|
47
|
-
"nodemailer": "^6.
|
|
47
|
+
"nodemailer": "^6.8.0",
|
|
48
48
|
"passport": "^0.6.0",
|
|
49
49
|
"passport-azure-ad": "^4.3.4",
|
|
50
50
|
"soap": "^0.45.0",
|
|
51
|
-
"tedious": "^15.1.
|
|
51
|
+
"tedious": "^15.1.2",
|
|
52
52
|
"winston": "^3.8.2"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|