Add a client role to a keycloak user using java
Asked Answered
M

2

7

I am using the Keycloak Admin Client library to attempt to create a user and then add a client role to that created user. I am creating the user with no problems, however when I am trying to assign a role to that user I am receiving the error:

javax.servlet.ServletException: java.lang.IllegalStateException: RESTEASY003765: Response is closed.
    org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:487)
    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:441)
    org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:169)

Here is my code where it is breaking:

// Get realm
        RealmResource realmResource = keycloak.realm(realm);
        UsersResource userRessource = realmResource.users();

                System.out.println(userId);

        // Get client
        ClientRepresentation app1Client = realmResource.clients()
                .findByClientId("digicor").get(0);

                System.out.println("app1Client.getId: "+app1Client.getId());

                System.out.println("realmResource.clients()) = "+ realmResource.clients().toString());

                System.out.println("realmResource.roles().list() ="+realmResource.roles().list());

                System.out.println("realmResource.roles().list().get(0) ="+realmResource.roles().list().get(0));

                System.out.println(" realmResource.clients().findAll() ="+ realmResource.clients().findAll());

                System.out.println(" realmResource.clients().findAll().get(0).toString ="+ realmResource.clients().findAll().toString());

                System.out.println("realmResource.clients().get(digicor) = "+ realmResource.clients().get("digicor"));

                System.out.println("realmResource.clients().get(digicor).roles() = "+ realmResource.clients().get("digicor").roles());

                System.out.println("realmResource.clients().get(\"digicor\").roles().get(\"development\") = "+ realmResource.clients().get("digicor").roles().get("development").toString());

                RoleRepresentation clientRole = realmResource.clients().get("digicor").roles().get("development").toRepresentation();
      //Breaks on the above line and never reaches this print.           
                System.out.println("Role Representation made");

Here is my pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>portalbackend</groupId>
    <artifactId>portalbackend</artifactId>
    <version>1</version>
    <properties>
        <keycloak.version>3.4.3.Final</keycloak.version>
        <resteasy.version>3.5.0.Final</resteasy.version>
    </properties>
    <packaging>war</packaging>
    <build>
        <finalName>portalbackend</finalName>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <warSourceDirectory>WebContent</warSourceDirectory>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>

                <!-- Docker configuration to build images using maven-->
                <plugin>
                    <groupId>com.spotify</groupId>
                    <artifactId>docker-maven-plugin</artifactId>
                    <version>0.4.10</version>
                    <configuration>
                        <imageName>usmanwajid/portalbackend</imageName>
                        <imageTags>
                            <imageTag>1.1</imageTag>
                        </imageTags>
                        <dockerDirectory>.</dockerDirectory>
                        <!--<dockerHost>https://192.168.99.100:2376</dockerHost>-->
                        <resources>
                            <resource>
                                <targetPath>/</targetPath>
                                <directory>${project.build.directory}</directory>
                                <include>${project.build.finalName}.war</include>
                            </resource>
                        </resources>
                    </configuration>
                </plugin>
                <!--New -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.5.1</version>
                    <dependencies>

                    </dependencies>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                    </configuration>
                </plugin>
                <!--New END -->
            </plugins>
        </pluginManagement>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-catalina</artifactId>
            <version>8.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.22.1</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.22.1</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>2.22.1</version>
            <type>jar</type>
        </dependency>

        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.0.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.mail/mail -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.13</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.json</artifactId>
            <version>1.0.4</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>

        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>

        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.5.0</version>
        </dependency>


        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver</artifactId>
            <version>3.5.0</version>
        </dependency>

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <type>jar</type>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.codehaus.jettison/jettison -->
        <dependency>
            <groupId>org.codehaus.jettison</groupId>
            <artifactId>jettison</artifactId>
            <version>1.3.8</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-admin-client</artifactId>
            <version>${keycloak.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jaxrs -->
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>${resteasy.version}</version>
        </dependency>


        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-client</artifactId>
            <version>${resteasy.version}</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson2-provider</artifactId>
            <version>${resteasy.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-multipart-provider -->
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-multipart-provider</artifactId>
            <version>${resteasy.version}</version>
        </dependency>


    </dependencies>

    <name>portalbackend</name>
</project>

I am building this project with maven and then running it as a docker image on a server.

Any help would be greatly appreciated, Thanks.

Mulligatawny answered 5/3, 2018 at 12:13 Comment(2)
You must be reading the response twice somewhere #35596207Medorra
Thanks for the response. I have looked through my code and I cannot see where I am reading the response at all. On the above code it's only breaking on the part where I am trying to convert it to a RoleRepresentation, all of the other print's are successful.Mulligatawny
T
11

I assigned Role to the user in following way

String userRole = "development";

List<RoleRepresentation> roleRepresentationList = userResource.roles().realmLevel().listAvailable();

for (RoleRepresentation roleRepresentation : roleRepresentationList)
  {
    if (roleRepresentation.getName().equals(userRole))
      {
        userResource.roles().realmLevel().add(Arrays.asList(roleRepresentation));
        break;
     }
  }

If You want to assign Client Level roles to User , you do as follows

ClientRepresentation clientRep = realmResource.clients().findByClientId("digicor").get(0);
RoleRepresentation clientRoleRep = realmResource.clients().get(clientRep.getId()).roles().get("development").toRepresentation();
userResource.roles().clientLevel(clientRep.getId()).add(Arrays.asList(clientRoleRep));
Tombac answered 6/3, 2018 at 0:23 Comment(4)
Thanks for the response Ravthiru! I am able to add realm roles in this way so thank you. However my problem is that I am trying to add a role from a client to the user rather than a realm level role. Roles > Default roles > Select client > Here.Mulligatawny
You should use realmResource.clients().findByClientId("digicor") instead of realmResource.clients().get("digicor"). See my updateTombac
Hi @ravthiru, How can i create client role or realm level role, before adding it to an user. Please helpHousebreaker
Code works still in Keycloak 21.0.0. I also changed userResource.roles().clientLevel(clientRep.getId()).add(Arrays.asList(clientRoleRep)); to userResource.roles().clientLevel(clientRep.getId()).add(List.of(clientRoleRep)); using List.of(...).Cumuliform
E
0

I tried your solutions. However I am getting issues. We use the latest Keycloak server.

I added a new role for a particular clientid from my code.

ClientResource cliR =  keycloak.realm("master").clients().get(clientrep.getId());
            
cliR.roles().create(rRep);

I am trying to assign this client role to a user. However I am getting a 404 error.

keycloak.realm("master").users().get(userid).roles().clientLevel(clientRep.getId()).add(Arrays.asList(RoleRepresentation));
jakarta.ws.rs.NotFoundException: HTTP 404 Not Found
    at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.handleErrorStatus(ClientInvocation.java:242)
    at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.DefaultEntityExtractorFactory$3.extractEntity(DefaultEntityExtractorFactory.java:41)
    at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invokeSync(ClientInvoker.java:136)
    at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:103)
    at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:61)
    at com.sun.proxy.$Proxy45.add(Unknown Source)

I believe there should be some setting on the Keycloak which needs to be set.

The current set up is clientid is authorization enabled with the Roles mapped for manage-clients and manage-users for the master Realm.

Appreciate your help.

Ecotype answered 31/5, 2024 at 18:9 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.