Rasha Elsayed
Rasha Elsayed

Reputation: 740

Keycloak Admin REST-API Synchronize federation mapper

I am using Keycloak 9.0.3 with a LDAP-user federation, with edit mode = WRITABLE and Import Users = on. I am developing a spring boot application that should call the Keycloak REST API to create, update, delete users and groups in LDAP. I also created "group-ldap-mapper" in my user federation to map LDAP-Groups to Keycloak-Groups and vise-versa.

My requirement is to create and delete Keycloak-groups via the REST API and they get mapped to groups in LDAP using the mapper above. When my application calls POST /{realm}/groups Keycloak just creates the group in Keycloak-DB and does not synchronise to LDAP unless the group gets assigned to some user. This is actually not a big problem. The real problem is when my application deletes the group via DELETE /{realm}/groups/{id}. The groups gets deleted from the Keycloak-DB but not from LDAP. An acceptable workaround would be to call POST /{realm}/user-storage/{parentId}/mappers/{id}/sync which synchronises the Groups and does the job.

The problem in this workaround, that there is no way to get the federation mapper id ({id}) other than hardcoding it in the spring application. There is no REST-Call to retrieve this id programatically.

Any idea how to solve this?

Upvotes: 0

Views: 3472

Answers (2)

Edmilson Santana
Edmilson Santana

Reputation: 361

Just for the records,

based on the solution I incorporated it into keycloak-api-ts

Here is an example code on how to use it:

    import KeycloakAPI, { ServerSettings } from '../lib/index';
    import { ActionType } from '../lib/api/user-storage-provider/index';
    
    type Config = {
      realm: string;
      id: string,
      mode: ActionType
    }
    
    const importerConfig: Config = {
      realm: process.env.KC_MSP_IMPORTER_REALM || 'master',
      id: process.env.KC_MSP_IMPORTER_ID || '<<importerId>>',
      mode: process.env.KC_MSP_IMPORTER_MODE as ActionType || 'triggerFullSync'
    };
    
    const settings: ServerSettings = require('../.keycloakSettings.json');
    
    
    const kcSyncUsers = async () => {
      const kcApi: KeycloakAPI = new KeycloakAPI(settings);
      const importResult = kcApi.userStorageProvider
        .syncUsers(
          importerConfig.realm,
          importerConfig.id,
          importerConfig.mode
        )
        .then((ir) => {
          if (ir.success === true) {
            return ir.data;
          } else {
            throw new Error(ir.statusText);
          }
    
        })
        .catch((e) => {
          console.error(e);
          return {
            message: e.message
          }
        });
      return importResult;
    };
    
    kcSyncUsers();

Upvotes: 0

Rasha Elsayed
Rasha Elsayed

Reputation: 740

I figured out how to find the ids of the federation and the group-ldap-mapper programatically to use them in the call POST /{realm}/user-storage/{parentId}/mappers/{id}/sync.

One can call GET /{realm}/components. This returns among other things federation and mappers. In my case I could find the federation id from the UserRepresentation and then I used it to filter the components (parent={federation id}). According to documentation there is also a type Query, but I could not figure out the right value.

Upvotes: 1

Related Questions