15

I was able to create user in Keycloak by posting a json containing only 1 user using postman.

http://localhost:8080/auth/admin/realms/master/users

But when i tried to create more than 1 user by passing a json array of more than 1 record i am getting a 500 Internal server error

[
  {
    "username": "user1",
    "firstName": "John",
    "attributes": {
      "pl_uid": null
    },
    "credentials": [
      {
        "temporary": true,
        "type": "password",
        "value": "ares2012"
      }
    ]
  },
  {
    "username": "1000195",
    "firstName": "Matt",
    "attributes": {
      "pl_uid": null
    },
    "credentials": [
      {
        "temporary": true,
        "type": "password",
        "value": "rx3o0t9f"
      }
    ]
  }
]

Is there any way by which we can send a json array to keycloak and create users there?

Midhun Gopinath
  • 291
  • 2
  • 4
  • 13

3 Answers3

6

Please have a look on the discussion added in Keycloak mailing list

Just double checked the approach I suggested. I thought we had made it possible to import users into an existing realm, but that's not the case. You have to create the whole realm. It's still possible to do it this way, first create the realm and add an example user. Stop the server and run it again with:

 bin/standalone.sh -Dkeycloak.migration.action=export -Dkeycloak.migration.provider=dir -Dkeycloak.migration.realmName=<realm name> -Dkeycloak.migration.dir=<dir name>
  • Replace realm name and dir name

In dir name you should then get a few json files. You can then update realm name-users-0.json to add the users you want to import.

As Bill points out the admin client could be a good alternative approach. We also have a Java client that makes it simpler to use. Have a look at the admin-client example.

So this URL can help. Have a look at this link

Another option is using partialImport API for importing users (use admin user token):

access_token=`curl --data "grant_type=password&username=admin&password=admin&client_secret=secret&client_id=admin-cli" http://localhost:8180/auth/realms/master/protocol/openid-connect/token| jq -r .access_token`

curl -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -H "Authorization: Bearer $access_token"  --data "@$PWD/myrealm-users-0.json"  http://localhost:8180/auth/admin/realms/myrealm/partialImport
Dark Star1
  • 6,986
  • 16
  • 73
  • 121
Subodh Joshi
  • 12,717
  • 29
  • 108
  • 202
  • Seems not working anymore with 19.0.1. Error: {"error":"RESTEASY003210: Could not find resource for full path: http://localhost:8080/auth/admin/realms/myrealm/partialImport"}% – Jeff Tian Nov 30 '22 at 11:53
  • I echo the same, not working with keycloak 20.0 version. Looking for some options bulk importing users. – Lokesh Jun 05 '23 at 19:38
5

After checking Keycloak's REST API doesn't look like bulk/batch requests for creating users are accepted. The only solution would be to send the POST request for every user.

This is not surprising, HTTP is not prepared for this kind of requests:

As HTTP does not provide proper guidance for handling batch/bulk requests and responses.

from this RESTful guide. Have a look to it, it's really usefull in REST devlopments.

0

I checked the paritalImport approach as suggested by others, it seems not available anymore in later versions such as 19.0.1. The error message is something like {"error":"RESTEASY003210: Could not find resource for full path: localhost:8080/auth/admin/realms/myrealm/partialImport"}%.

So I invoke Keycloak API to create users, one by one though. But as long as we can use a program to do it, it's also acceptable.

For example, we can write some java code to invoke the creating user API:

    public String createUser(UserPayload user) throws IOException {
        var url = "https://keycloak.jiwai.win/auth/admin/realms/UniHeart/users";
        var payload = java.lang.String.format("{\"firstName\":\"Sergey\",\"lastName\":\"Kargopolov\", \"email\":\"%s\", \"enabled\":\"true\", \"username\":\"%s\", \"credentials\":[{\"type\":\"password\",\"value\":\"%s\",\"temporary\":false}]}", user.getEmail(), user.getUsername(), user.getPassword());
        return this.jsonRequest(url, payload).toString();
    }

The above code is merely calling the create user API. But to call it successfully we need firstly got the admin access token:


    public KeycloakAccessTokenPayload getAdminAccessToken() throws IOException {
        var username = System.getenv("KC_ADMIN");
        var password = System.getenv("KC_PASSWORD");

        System.out.println(java.lang.String.format("username = %s; password = %s", username, password));

        var mediaType = MediaType.parse("application/x-www-form-urlencoded");
        var body = RequestBody.create(mediaType, java.lang.String.format("username=%s&password=%s&grant_type=password&client_id=admin-cli", username, password));
        var request = new Request.Builder()
                .url("https://keycloak.jiwai.win/auth/realms/master/protocol/openid-connect/token")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        var response = client.newCall(request).execute();

        var s = Objects.requireNonNull(response.body()).string();

        System.out.println(java.lang.String.format("token response = %s", s));

        return JsonHelper.parseFrom(s);
    }

And then pass the admin access token to the target API by setting the HTTP header:


    public Response jsonRequest(String url, String payload) throws IOException {
        var mediaType = MediaType.parse("application/json");
        var body = RequestBody.create(mediaType, payload);
        var request = new Request.Builder().url(url).method("POST", body).addHeader("Content-Type", "application/json").addHeader("Authorization", java.lang.String.format("Bearer %s", getAdminAccessToken().access_token)).build();
        var res = client.newCall(request).execute();

        System.out.println(java.lang.String.format("jsonRequest response = %s", res.toString()));

        return res;
    }

The fully working example is here: https://github.com/Jeff-Tian/keycloak-springboot/blob/main/src/main/java/com/example/keycloakspringboot/KeycloakHelper.java#L29

Jeff Tian
  • 5,210
  • 3
  • 51
  • 71