Skip to content

Commit

Permalink
Admin-client compatibility with the future Keycloak server versions
Browse files Browse the repository at this point in the history
closes #94

Signed-off-by: mposolda <mposolda@gmail.com>
  • Loading branch information
mposolda committed Oct 24, 2024
1 parent 8b82bb6 commit 076f015
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 23 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ and hence are supposed to be updated there (whenever needed) and synced into thi
## Syncing the files from Keycloak repository

* Checkout [main Keycloak server repository](https://github.com/keycloak/keycloak) and build it on your laptop to make sure latest Keycloak stuff available in your local maven repository.
* Fetch [main Keycloak server repository](https://github.com/keycloak/keycloak) and checkout the last `release/X.Y` branch (For example `git checkout release/26.0` ). Note that we usually
cannot sync from the server `main` branch as it is under development and there is still a chance that some things being developed here would be later updated/removed.
Which could be an issue as for client, we want to preserve backwards compatibility.

* build it on your laptop to make sure latest Keycloak stuff available in your local maven repository.

* Run [sync-keycloak-sources.sh](.github/scripts/sync-keycloak-sources.sh)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.keycloak.admin.client;

import com.fasterxml.jackson.databind.DeserializationFeature;
import jakarta.ws.rs.core.MediaType;

import com.fasterxml.jackson.annotation.JsonInclude;
Expand All @@ -14,6 +15,9 @@ public ObjectMapper locateMapper(Class<?> type, MediaType mediaType) {

// Same like JSONSerialization class. Makes it possible to use admin-client against older versions of Keycloak server where the properties on representations might be different
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

// The client must work with the newer versions of Keycloak server, which might contain the JSON fields not yet known by the client. So unknown fields will be ignored.
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

return objectMapper;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.jboss.resteasy.client.jaxrs.engines.ClientHttpEngineBuilder43;
import org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.JacksonProvider;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.keycloak.client.testsuite.models.Constants;
Expand Down Expand Up @@ -70,8 +71,8 @@ public static Keycloak createAdminClient(boolean ignoreUnknownProperties, String

public static Keycloak createAdminClientWithClientCredentials(String realmName, String clientId, String clientSecret, String scope) {

boolean ignoreUnknownProperties = false;
ResteasyClient resteasyClient = createResteasyClient(ignoreUnknownProperties, null);
boolean ignoreUnknownProperties = true;
ResteasyClient resteasyClient = createResteasyClient(null);

return KeycloakBuilder.builder()
.serverUrl(getAuthServerContextRoot())
Expand All @@ -91,29 +92,14 @@ public static Keycloak createAdminClient(boolean ignoreUnknownProperties) throws
return createAdminClient(ignoreUnknownProperties, getAuthServerContextRoot());
}

public static ResteasyClient createResteasyClient() {
try {
return createResteasyClient(false, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static ResteasyClient createResteasyClient(boolean ignoreUnknownProperties, Boolean followRedirects) {
public static ResteasyClient createResteasyClient(Boolean followRedirects) {
ResteasyClientBuilder resteasyClientBuilder = (ResteasyClientBuilder) ResteasyClientBuilder.newBuilder();
resteasyClientBuilder.sslContext(buildSslContext());

// We need to ignore unknown JSON properties e.g. in the adapter configuration representation
// during adapter backward compatibility testing
if (ignoreUnknownProperties) {
// We need to use anonymous class to avoid the following error from RESTEasy:
// Provider class org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider is already registered. 2nd registration is being ignored.
ResteasyJackson2Provider jacksonProvider = new ResteasyJackson2Provider() {};
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
jacksonProvider.setMapper(objectMapper);
resteasyClientBuilder.register(jacksonProvider, 100);
}
// We need to use subclass (or anonymous class) to avoid the following error from RESTEasy:
// Provider class org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider is already registered. 2nd registration is being ignored.
ResteasyJackson2Provider jacksonProvider = new JacksonProvider();
resteasyClientBuilder.register(jacksonProvider, 100);

resteasyClientBuilder
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.WILDCARD)
Expand Down

0 comments on commit 076f015

Please sign in to comment.