keycloakkeycloak-services

How to create a user in Keycloak SPI?


Good Day All, I am trying to create a user inside keycloak custom API. Right now I am using keycloak-admin-client to create user. But I don't want to use keycloak-admin-client.

Following is a sample code for my existing API using right now,

package com.mycustom.keycloak.api;

import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.services.managers.AppAuthManager;
import org.keycloak.services.managers.AuthenticationManager.AuthResult;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.representations.idm.UserRepresentation;

public class MyController {

    private RealmModel realm;
    private AuthResult authResult;
    private KeycloakSession session;
    private RequestManagement apiMethod;
    private AuthorisationTokenManagment auth;

    public MyController(KeycloakSession session) {
        this.session = session;
        this.realm = session.getContext().getRealm();
        this.apiMethod = new RequestManagement();
        this.auth = new AuthorisationTokenManagment(session);
        this.authResult = new AppAuthManager.BearerTokenAuthenticator(session).authenticate();

    }

    @POST
    @Path("idp/create-user")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response createUser(User member) {
        helper.checkTokenValidationThrowError(this.authResult);

        // check if phone number exist already or not
        if (member.getAttributes().get("phone_number") != null
                && member.getAttributes().get("country_code") != null) {
            HashMap<String, String> attributeFilter = new HashMap<>();
            attributeFilter.put("phone_number", member.getAttributes().get("phone_number"));
            attributeFilter.put("country_code", member.getAttributes().get("country_code"));
            Stream<UserModel> userStream = session.users().searchForUserStream(this.realm, attributeFilter);
            List<UserModel> userList = userStream.toList();

            if (null != userList && !userList.isEmpty() && userList.size() == 1) {
                String errorMessage = "{\"errorMessage\": \"User exists with same phone number\"}";
                return Response.ok().entity(errorMessage).status(409).type(MediaType.APPLICATION_JSON).build();
            }
        }


        //crate user using `keycloak-admin-client`
        <!-- code to create user with keycloak-admin-client -->
        
        if (201 == statusCode) {
            return Response
                    .status(201)
                    .header("Location",
                            session.getContext().getUri().getBaseUri() + "admin/realms/" + realm.getName()
                                    + "/users/" + memberId)
                    .type(MediaType.APPLICATION_JSON)
                    .build();
        } else {
            return Response.ok()
                    .entity(response.body())
                    .status(statusCode)
                    .type(MediaType.APPLICATION_JSON)
                    .build();
        }
    }
}

Is there any other way to create a user by extending any keycloak classes?


Solution

  • I was able to find the solution. For creating a user, we can simply use UserProvider from KeycloakSession.

    Import statements

    import org.keycloak.models.UserModel;
    import org.keycloak.models.RealmModel;
    import org.keycloak.models.RoleModel;
    import java.util.Arrays;
    

    Code to insert new user with role

    String username = "prifulnath";
    UserModel newUserModel = session.users().addUser(realm, username);
    newUserModel.setEnabled(true);
    newUserModel.setUsername(username);
    newUserModel.setEmail("test@mail.com");
    newUserModel.setFirstName("test");
    newUserModel.setLastName("name");
    newUserModel.setAttribute("phone_number", Arrays.asList("123456789"));
    newUserModel.addRequiredAction("UPDATE_PASSWORD");
    RoleModel roleModel = realm.getClientByClientId("client_id").getRole("guest");
    if (null != roleModel) {
        newUserModel.grantRole(roleModel);
    }