-
Bug
-
Resolution: Done
-
Normal
-
None
-
None
-
1
-
False
-
-
False
-
Make the maximum concurrency of requests to the Keycloak server configurable to prevent server overloading. Fix issue with token update. Speed up parsing and conversion of Keycloak users and groups for the Backstage API.
-
Bug Fix
-
-
-
RHDH Plugins 3266, RHDH Plugins 3267, RHDH Plugins 3268, RHDH Plugins 3269
[2627201995] Upstream Reporter: JohannesWill
Upstream issue status: Open
Upstream description:
Describe the bug
I have setup the Keycloak backend plugin by following the steps given on below this link - https://janus-idp.io/plugins/keycloak/ .
Syncing the users and Groups will overload our Keycloak instance by doing many parrallel requests
Expected Behavior
- All users and groups from keyclock realm should be synced
- The Keycloak server should not experience a DoS (Denial of Service).
What are the steps to reproduce this bug?
- Keycloak with many users and groups (in my case ~2500 users and 850 groups)
- Configure the Keycloak plugin for new backup configuration (using steps from https://janus-idp.io/plugins/keycloak/)
Versions of software used and environment @janus-idp/backstage-plugin-keycloak-backend": "^2.0.8",
Backstage - 1.30.4 (create-app@0.5.18
)
Temporary Workaround: During investigation of that problem I used patch-package to patch @janus-idp/backstage-plugin-keycloak-backend@2.0.8 for the project I'm working on. With that pacht, where I serialized the calls to Keycloak, the problem is not reproduceable anymore.
Here is the diff that solved my problem:
Unable to find source-code formatter for language: diff. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yamldiff --git a/node_modules/@janus-idp/backstage-plugin-keycloak-backend/dist/index.cjs.js b/node_modules/@janus-idp/backstage-plugin-keycloak-backend/dist/index.cjs.js index a0e323e..180abfc 100644 --- a/node_modules/@janus-idp/backstage-plugin-keycloak-backend/dist/index.cjs.js +++ b/node_modules/@janus-idp/backstage-plugin-keycloak-backend/dist/index.cjs.js @@ -153,17 +153,19 @@ async function getEntities(entities, config, logger, entityQuerySize = KEYCLOAK_ const rawEntityCount = await entities.count({ realm: config.realm }); const entityCount = typeof rawEntityCount === "number" ? rawEntityCount : rawEntityCount.count; const pageCount = Math.ceil(entityCount / entityQuerySize); - const entityPromises = Array.from( - { length: pageCount }, - (_, i) => entities.find({ - realm: config.realm, - max: entityQuerySize, - first: i * entityQuerySize - }).catch( - (err) => logger.warn("Failed to retieve Keycloak entities.", err) - ) - ); - const entityResults = (await Promise.all(entityPromises)).flat(); + const entityResults = []; + for (let i = 0; i < pageCount; i++) { + try { + const entitiesPage = await entities.find({ + realm: config.realm, + max: entityQuerySize, + first: i * entityQuerySize + }); + entityResults.push(...entitiesPage); + } catch (err) { + logger.warn("Failed to retrieve Keycloak entities.", err); + } + } return entityResults; } async function getAllGroupMembers(groups, groupId, config, options) { @@ -254,35 +256,36 @@ const readKeycloakRealm = async (client, config, logger, options) => { [] ); } - const kGroups = await Promise.all( - rawKGroups.map(async (g) => { - g.members = await getAllGroupMembers( - client.groups, - g.id, - config, - options - ); - if (isVersion23orHigher) { - if (g.subGroupCount > 0) { - g.subGroups = await client.groups.listSubGroups({ - parentId: g.id, - first: 0, - max: g.subGroupCount, - briefRepresentation: false, - realm: config.realm - }); - } - if (g.parentId) { - const groupParent = await client.groups.findOne({ - id: g.parentId, - realm: config.realm - }); - g.parent = groupParent?.name; - } + const kGroups = []; + for (const g of rawKGroups) { + g.members = await getAllGroupMembers( + client.groups, + g.id, + config, + options, + ); + + if (isVersion23orHigher) { + if (g.subGroupCount > 0) { + g.subGroups = await client.groups.listSubGroups({ + parentId: g.id, + first: 0, + max: g.subGroupCount, + briefRepresentation: false, + realm: config.realm, + }); + }? + if (g.parentId) { + const groupParent = await client.groups.findOne({ + id: g.parentId, + realm: config.realm, + }); + g.parent = groupParent?.name; } - return g; - }) - ); + } + + kGroups.push(g); + } const parsedGroups = await kGroups.reduce( async (promise, g) => { const partial = await promise;This issue body was partially generated by patch-package.
Upstream URL: https://github.com/janus-idp/backstage-plugins/issues/2471
- links to