connected Forum discussion: https://keycloak.discourse.group/t/creating-a-simple-custom-keycloak-http-rest-endpoint/23773
official keycloak rest-api example:https://github.com/keycloak/keycloak/tree/24.0.2/examples/providers/rest/src/main/java/org/keycloak/examples/rest
None of which solved my issue, I tried the three solutions from RealmResourceProvider is not working as expected since version 23.0.0 #25882, tested the code from dasniko with the provided docker container (which has keycloak version 23.0.7) and even copied the official example into my project. I still get the 405 error.
Here is a minimal example to test it:
import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.services.resource.RealmResourceProvider;
import org.keycloak.services.resource.RealmResourceProviderFactory;
public class testFactory implements RealmResourceProviderFactory {
@Override
public RealmResourceProvider create(KeycloakSession keycloakSession) {
return new testProvider(keycloakSession);
}
@Override
public void init(Config.Scope scope) { }
@Override
public void postInit(KeycloakSessionFactory keycloakSessionFactory) { }
@Override
public void close() { }
@Override
public String getId() {
return "api-" + "test";
}
}
and
import org.jboss.logging.Logger;
import org.keycloak.models.KeycloakSession;
import org.keycloak.services.resource.RealmResourceProvider;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
public class testProvider implements RealmResourceProvider {
private static final Logger logger = Logger.getLogger(
testProvider.class);
public testProvider(KeycloakSession session) {
logger.info("[API::testProvider] constructor");
}
@Override
public void close() {
logger.info("[API::testProvider] close");
}
@Override
public Object getResource() {
logger.info("[API::testProvider] get resource");
return this;
}
@GET
@Path("")
@Produces("text/plain; charset=utf-8")
public Response getAlive() {
logger.info("[API::testProvider] get Alive");
return Response.status(200).entity("api is working").build();
}
}
The resources/META-INF folder contains an empty beans.xml and the services folder.
The GET request was sent to the URL: http://localhost:8080/admin/master/api-test/
This is wrong, your endpoint is not available under the /admin path, it’s in the regular /realms path and should be http://localhost:8080/realms/master/api-test/.
If I call it with the admin path, I get a 404 (expected), but I don’t get ever a 405.
So, I don’t know what’s going on in your environment, sorry.
Two other things, related to general Java development (not related to your 405):
Classnames in Java always start with an uppercase letter, so your classes should be TestFactory and TestProvider
Your expression “package+Class name” is called fully-qualified-class-name, or fqcn
Thanks for the fast answer, I was indeed using the incorrect URL when trying your environment.
But using your API in my code still results in a 405 (using the correct URL), could using multiple Factories be a problem?
It used to work in Version 22 with me adding all Factory classes within the org.keycloak.services.resource.RealmResourceProviderFactory File, like dasniko.keycloak.resource.MyResourceProviderFactory, with one class per line.
Could this be an error source? Do you know whether I need to change something else when using multiple classes this way?
Having multiple entries in the services files is the proper approach and way to go. I don’t know of any problems that this won’t work. I do it the same way, there is no other way.
The examples from my repository work as expected, I also just added your classes to my repo, deployed it and it just worked.
I still encounter the same issue. It works in kc version 22 and it works well in our production. Now I need to upgrade to version 24.0.2, the issue happens. Following is my example.Could you give me some suggestions? Thanks Factory:
@AutoService(RealmResourceProviderFactory.class)
// I used to config the factory in the META-INF, it still doesn't work in version 24+
public class TestConfigurationResourceProviderFactory implements RealmResourceProviderFactory {
@Override
public RealmResourceProvider create(KeycloakSession session) {
return new TestConfigurationResourceProvider (session);
}
@Override
public void init(Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return "test-configurations";
}
Provider:
@RequiredArgsConstructor
public class TestConfigurationResourceProvider implements RealmResourceProvider {
private final KeycloakSession session;
@Override
public Object getResource() {
return new TestConfigurationResource (session);
}
@Override
public void close() {
}
}
Resource:
@RequiredArgsConstructor
public class TestConfigurationResource {
private final KeycloakSession session;
@GET
@Path("")
@Produces(APPLICATION_JSON)
public Response getTestConfiguration() {
return Response.ok(Map.of("hello", session.getContext().getRealm().getName())).build();
}
}
I have tried the solution from this link https://github.com/keycloak/keycloak/issues/25882, but it still doesn’t work.
Besides I have tried clean the mvn repo in my local env, but it still failed, who can help me ???
Hello Ermi, have you solved the problem? It blocked me 5 days. I tried all the solutions @dasniko refered, but it failed. Besides, I have cleaned the org.* folder in local mvn repository, it still doesn’t work. Looking forward you give me some suggestions.
Hello @ulftid,
We needed to create a new repo that was based on the tutorials and then just added our existing code. I think there was some error coming from clashing versions of some of the packages.