Keycloak API createUser Java
Asked Answered
I

3

5

Sample Java Code I use:

public static AjaxResponse createUser(User newUser) {

    Keycloak keycloak = Keycloak.getInstance(
            SERVER_URL,
            REALM,
            USERNAME,
            PASSWORD,
            CLIENT_ID);

    // Get Realm
    RealmResource realmResource = keycloak.realm(REALM);
    UsersResource userResource = realmResource.users();

    // Create User Representation
    UserRepresentation user = getUserRepresentation(newUser);

    // Create user (requires manage-users role)
    try {
        System.out.println("Username: {}", userResource.get("USER-ID-HERE").toRepresentation().getUsername());            
        System.out.println("Count: " + userResource.count());
        Response response = userResource.create(user);
        System.out.println("Response: " + response.getStatusInfo());
        System.out.println("Response: " + response.getStatus());
        System.out.println("Response: " + response.getMetadata());

    } catch (Exception e) {
        System.out.println(ExceptionUtils.getStackTrace(e));
        return new AjaxResponse("Fail", false);
    }

    return new AjaxResponse("Successful User Creation", true);
}

private static UserRepresentation getUserRepresentation(User newUser) {

    UserRepresentation user = new UserRepresentation();
    user.setEnabled(true);
    user.setUsername(newUser.getUsername());
    user.setFirstName(newUser.getFirstName());
    user.setLastName(newUser.getLastName());
    user.setEmail(newUser.getEmail());

    CredentialRepresentation credentialRepresentation = new CredentialRepresentation();
    credentialRepresentation.setTemporary(true);
    credentialRepresentation.setType(CredentialRepresentation.PASSWORD);
    credentialRepresentation.setValue(newUser.getUsername());
    user.setCredentials(Collections.singletonList(credentialRepresentation));

}

The response I get when I run the code:

Username: USERNAME Correctly Identified here
Count: 98
Response: Conflict
Response: 409
Response: [Connection=keep-alive,Content-Length=46,Content-Type=application/json,Date=Tue, 03 Jul 2018 15:27:58 GMT,Server=WildFly/10,X-Powered-By=Undertow/1]`

Some thoughts: I added the count so to identify if the whole connection works at all. And it seems that the count returned is correct. So I successfully connect to keycloak but something else goes wrong when I try to create a user.

The dependencies in my pom.xml

    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-servlet-filter-adapter</artifactId>
        <version>3.2.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-admin-client</artifactId>
        <version>3.2.1.Final</version>   (Have also tried 3.1.0.Final and 3.2.0.Final)
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-client</artifactId>
        <version>3.1.4.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jackson2-provider</artifactId>
        <version>3.1.4.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <version>3.1.4.Final</version>
    </dependency>

As I understood those dependencies are related as well:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-version}</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jackson-version}</version>
    </dependency>

Other info:

Keycloak Version I use: 3.2.0

The Keycloak API can be found here

More information on the HTTP 409 Code can be found here

I would much appreciate any help or any guidance. Note Credentials and all variables have been checked, once, twice, thrice, and 10 times again. I've been searching for a complete working example. But most fail to specify the dependencies required and thus my code fails.

Note: I am also using Tomcat-8 and as I am searching deeper into the issue. I see that there are probably some special configurations for Tomcat8. Note that the authentication sign-in sign-out for my web-app already works as expected.

Interfluve answered 3/7, 2018 at 15:50 Comment(5)
keycloak-admin-client version and your server version should be same , You get 409 when trying to create user with same name and in same realmAttemper
As I've written above, I have tried with other versions as well, it doesn't work. And the 409 issue you describe has been checked more than 3 times.Interfluve
Check if you are getting any error message using Object entity = response.getEntity(); String errorMessage = ""; if (entity instanceof ErrorRepresentation) errorMessage = ((ErrorRepresentation) entity).getErrorMessage(); else if (entity != null) errorMessage = entity.toString();Attemper
Thanks for the comment @Attemper . Just tried that but still no luck.Interfluve
Does that mean no error message from KeycloakAttemper
I
8

I finally got it to work. Here is the solution for future reference.

UserRepresentation userRepresentation = new UserRepresentation();
userRepresentation.setUsername("randomUser");
Response response = usersResource.create(userRepresentation);
logger.info("Response |  Status: {} | Status Info: {}", response.getStatus(), response.getStatusInfo());
String userId = response.getLocation().getPath().replaceAll(".*/([^/]+)$", "$1");
UserResource userResource = usersResource.get(userId);

I then update the userResource with further information.

Interfluve answered 6/7, 2018 at 8:45 Comment(1)
FYI you can use org.keycloak.admin.client.CreatedResponseUtil.getCreatedId(response) to get the id. Be sure to check the response statut code before calling this method as it can throw an exception if the response is not 201Matt
L
1
@Override
public UserDto registerNewUserAccount(final UserDto accountDto) {
    String keycloakPassword = accountDto.getPassword();

    accountDto.setPassword(passwordEncoder.encode(accountDto.getPassword()));
    accountDto.setEnabled(1);
    UserDto user = userRepository.save(accountDto);

    AuthorityDto role = new AuthorityDto();
    role.setUserName(accountDto.getLogin());
    role.setAuthority("ROLE_USER");

    authorityRepository.save(role);

    Keycloak kc = Keycloak.getInstance(
            "https://www.zdslogic.com/keycloak/auth",  /your server
            "zdslogic",  //your realm
            "richard.campion", //user 
            "Changit", //password
            "admin-cli"); //client


    CredentialRepresentation credential = new CredentialRepresentation();
    credential.setType(CredentialRepresentation.PASSWORD);
    credential.setValue(keycloakPassword);

    UserRepresentation keycloakUser = new UserRepresentation();
    keycloakUser.setUsername(accountDto.getLogin());
    keycloakUser.setFirstName(accountDto.getFirstName());
    keycloakUser.setLastName(accountDto.getLastName());
    keycloakUser.setEmail(accountDto.getEmail());
    keycloakUser.setCredentials(Arrays.asList(credential));
    keycloakUser.setEnabled(true);
    keycloakUser.setRealmRoles(Arrays.asList("user"));

    // Get realm
    RealmResource realmResource = kc.realm("zdslogic");
    UsersResource usersRessource = realmResource.users();

    // Create Keycloak user
    Response result = null;
    try {
        result = usersRessource.create(keycloakUser);
    } catch(Exception e) {
        System.out.println(e);
    }

    if (result==null || result.getStatus() != 201) {
        System.err.println("Couldn't create Keycloak user.");
    }else{
        System.out.println("Keycloak user created.... verify in keycloak!");
    }

    return user;

}
Loup answered 10/12, 2020 at 17:18 Comment(0)
C
0

The 409 conflict http status gives the hint.

Keycloak creates users and typically returns a conflict if the username or email is reused. Check to ensure that the resource being created contains a different username and email to ones already registered in a realm.

Easy method to check: - Log into the admin console - Navigate to realm - Navigate to users tab - Type username and search or email and search

Clapboard answered 3/7, 2018 at 18:49 Comment(1)
Thanks for the answer. I have checked that already. Unfortunately its something else.Interfluve

© 2022 - 2024 — McMap. All rights reserved.