Using keycloak-admin-client within a Keycloak extension

Hi all,

I previously (with the “legacy” version of Keycloak) had an extension that used keycloak-admin-client. I was able to deploy the jar and a module xml to wildfly and depend on this module in the extension. I am trying to update this extension, as it appears to no longer work the same way in the “quarkus” Keycloak version.

I’ve found a few posts about the mismatch of Resteasy versions (e.g. quarkus - How to use keycloak-admin-client with custom Keycloak provider - Stack Overflow) and a quarkus-keycloak-admin-client package (https://mvnrepository.com/artifact/io.quarkus/quarkus-keycloak-admin-client), but no instructions on how to use them properly with an extension deployed in “quarkus” Keycloak.

Has anyone had any experience doing this? Thanks!

Interesting approach… What‘s the use case for this?
Yet, I never hat the need to include the admin-client into an extension, it was all possible to use to KeycloakSession, which should be around in all of the SPIs.

But hell yeah, the RestEasy dependency hell… This also caused me some headaches in other places. The runtime version of RestEasy in Quarkus based distributions is 4.7.5, but in the admin-client it‘s still a 3.x version, AFAIK. There is a solved issue, that the RestEasy version will be aligned in KC19.
Resteasy 3.x and 4.x versions are not compatible.

1 Like

Great question. I had 2 reasons for building using the Admin API rather than KeycloakSession:

  1. Code reusability/portability. There were some functions that would be used both in extensions and in external batch jobs. Because I wanted to reuse as much as possible, it made sense to use the Admin API. There was also an existing codebase that had used the Admin API that I was building from, so it helped me not have to port it.
  2. Preservation of permissions. This was something that had always bugged me about using KeycloakSession directly when building a REST resource. When I was doing something that required changing a bunch of entities that didn’t map well to a single admin role, I would have to figure out all of the permissions required by looking into the Keycloak code, and then try to recreate that role checking at the start of my resource. Using the Admin API with the token passed by the caller allows me to rely on the permission evaluation of the existing REST resources, rather than bypassing it by using KeycloakSession directly.

Let me know if you see any flaws in my decision.

After a bit of fiddling, I found that the keycloak bug New Keycloak-X Admin Client 18.0.0 doesn't work on my provider · Issue #11973 · keycloak/keycloak · GitHub contains a fairly complete explanation of how to avoid the problem.

Thanks for the information about it being solved in Keycloak 19. I hope it works in a less hacky way.

1 Like

Ok, I understand. Thanks for explanation.
So, there is no real technical reason, but - don‘t get me wrong - some philosophic and lazyness reasons.

For me, the admin-client was (and still is) a 3rd party library for usage outside of Keycloak. Also, I‘m not part of the code-reuse-team, I try to avoid such things as much as I can, but this is a different discussion, not related to Keycloak and this board.

Yes, excluding the 3.x libs and manually including the needed 4.x libs for RestEasy will do the trick, but this is really a bad workaround, just because the Keycloak team didn‘t geht the dependency management right. Wich 19, things should become better and work as expected.

1 Like

Agreed that the “hack” is a bad workaround. Looking forward to a better situation in version 19.

Here’s the pom change that ultimately worked for me:

...
<dependency>
  <groupId>org.keycloak</groupId>
  <artifactId>keycloak-admin-client</artifactId>
  <version>18.0.2</version>
  <exclusions>
    <exclusion>
      <groupId>*</groupId>
      <artifactId>*</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.wildfly.client</groupId>
  <artifactId>wildfly-client-config</artifactId>
  <version>1.0.1.Final</version>
  <exclusions>
    <exclusion>
      <groupId>*</groupId>
      <artifactId>*</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.jboss.resteasy</groupId>
  <artifactId>resteasy-client</artifactId>
  <version>4.7.5.Final</version>
  <exclusions>
    <exclusion>
      <groupId>*</groupId>
      <artifactId>*</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.jboss.resteasy</groupId>
  <artifactId>resteasy-client-api</artifactId>
  <version>4.7.5.Final</version>
  <exclusions>
    <exclusion>
      <groupId>*</groupId>
      <artifactId>*</artifactId>
    </exclusion>
  </exclusions>
</dependency>
...