The Deep
The Deep

Reputation: 93

Implementing a SPI to extend Keycloak API - Could not find resource

I'm trying to create a custom resource on my Keycloak server to extend its rest API. So i'm implementing a SPI. Starting with a hello world.

At the moment my goal is to obtain a "hello" + name through a GET on http://localhost:8080/auth/admin/realms/myRealm/hello

I use Postman to requests the server. I'm able to get a user token on myRealm. I choose a user for which i have assigned the role View-users in the realm-managment Mapper.

So the builtin Keycloak Admin API works. e.g :http://localhost:8080/auth/admin/realms/myRealm/users/count returns the expected user count.

But the problem is i get an "error": "RESTEASY003210: Could not find resource for full path: http://localhost:8080/auth/admin/realms/myRealm/hello/" when requesting this endpoint.

Here's my setup (i read several guides) :

The module project's pom.xml include dependency for keycloak-core keycloak-server-spi keycloak-server-spi-private org.jboss.spec.javax.ws.rs

RealmResourceProvider implementation :

public class HelloWorldProvider implements RealmResourceProvider {

    private KeycloakSession session;

    public HelloWorldProvider(KeycloakSession session) {
        this.session = session;
    }

    @Override
    public Object getResource() {
        return this;
    }

    @GET
    @Path("/hello")
    @Produces("text/plain; charset=utf-8")
    public String get() {
        String name = session.getContext().getRealm().getDisplayName();
        if (name == null) {
            name = session.getContext().getRealm().getName();
        }
        return "Hello" + name;
    }

    @Override
    public void close() {
    }
}

Factory implementation :

public class HelloWorldProviderFactory implements RealmResourceProviderFactory {

    public static final String ID = "hello";

    @Override
    public String getId() {
        return ID;
    }

    @Override
    public int order() {
        return 0;
    }

    @Override
    public RealmResourceProvider create(KeycloakSession keycloakSession) {
        return new HelloWorldProvider(keycloakSession);
    }

    @Override
    public void init(Config.Scope scope) {
    }

    @Override
    public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
    }

    @Override
    public void close() {
    }
}

I also created the file src\main\resources\META-INF\org.keycloak.services.resource.RealmResourceProviderFactory it contains a reference to my HelloWorldProviderFactory

After packaging the jar, i put a copy of it in keycloak-9.0.3\standalone\deployments and after running standalone.bat the file keycloak-spi-rest-hello-1.0.jar.deployed is created.

Upvotes: 5

Views: 6301

Answers (5)

trislee
trislee

Reputation: 121

In my case, I had to omit /auth/admin. So my final worked url is: http://localhost:8080/realms/master/hello

Upvotes: 2

PotatoesMaster
PotatoesMaster

Reputation: 183

@alexb83's answer does not work for me, I had to omit the /admin part from the url:

http://localhost:8080/auth/realms/myRealm/hello/hello

Upvotes: 1

Hari
Hari

Reputation: 277

In my case I had mixed up the order of the sub-paths in the url when accessing the end-point, i.e. instead of

/user/customuser

I had given

/customuser/user

Upvotes: 0

The Deep
The Deep

Reputation: 93

So as alexb83 said, i missed the second /hello in the url.

As PotatoesMaster said, i had to omit /admin in the url.

In Addition the file org.keycloak.services.resource.RealmResourceProviderFactory was in a wrong folder : i missed \services.

The working path is :

src\main\resources\META-INF\services\org.keycloak.services.resource.RealmResourceProviderFactory

Upvotes: 2

alexb83
alexb83

Reputation: 191

Try this:

http://localhost:8080/auth/admin/realms/myRealm/hello/hello

because first 'hello' is the name of your factory ID, instead the second 'hello' is the path you set on the service.

Upvotes: 5

Related Questions