keycloakkeycloak-spi

Integrate groups from external storage into Keycloak


I'm in the process of updating our Keycloak to version 22. We have a database that contains users and RBAC roles these users may have.

The users are integrated by a custom UserStorageProvider, and that works just fine.

However, the old integration we had also started a scheduled task that synchronizes the groups in Keycloak with those in our database by creating or removing Keycloak groups.

This seems very hacky to me, beside being wasteful (this process is executed over and over even though the data rarely changes).

I already found GroupProviderFactory and GroupProvider. Shouldn't it be possible to reimplement those the same way as the UserStorageProvider?

To try it I have created a dummy implementation of GroupProviderFactory and GroupProvider. getId() of the former returns mygroupprovider and I have run kc.sh build --spi-group-provider=mygroupprovider.

However, that didn't work. getId() does get called, but not create. I couldn't find any documentation or examples, so I don't know if this just isn't possible in general, or if I'm doing something wrong.

So, can this be done, and if so, how?


Solution

  • I finally figured it out. My error was that I tried to enable the SPI in the build command, but not start, and you have to do it the other way round.

    So, to explain everything I did:

    1. Created an implementation of org.keycloak.models.GroupProvider, let's call it MyGroupProvider.

    2. Created an implementation of org.keycloak.models.GroupProviderFactory as GroupProviderFactory<MyGroupProvider>, let's call it MyGroupProviderFactory. The override for getId() has to return something unique, say "mygroupproviderid"

    3. In resources/META-INF/services added a file org.keycloak.models.GroupProviderFactory with the path of MyGroupProviderFactory

    4. Created and copied a jar into /opt/keycloak/providers/ as usual

    5. Executed kc.sh start with parameters --spi-group-provider=mygroupproviderid --spi-group-provider-mygroupproviderid-enabled=true

    And that's t.