How to best import users from legacy application?

Hi. I’m looking for a way to move a few thousand user accounts to Keycloak. The system which currently holds the user data will be shut down after. If I understand correctly, this could be done with user federation (Server Administration Guide) with a provider that stores all data in Keycloak’s database?

Some providers even import the user locally and sync periodically with the external store.

In the old system, the passwords were hashed with bcrypt. As far as I see, Keycloak doesn’t support bcrypt and a third-party plugin would be needed (GitHub - leroyguillaume/keycloak-bcrypt: Add BCrypt password provider in Keycloak). Is there a way around? For example, is it possible to import user data from federation upon login but take (and hash) the password as provided by the user?

I am by no means a Keycloak expert, but I may be facing a similar situation in the future. My thought was to simply extract the user data from the source database, transform and import it in the relevant locations directly in the Keycloak database with SQL… all but the password. Then outside of keycloak, send a mass email to the users advising them that a password reset is required and let them use the “Forgot password” functionality. If I can initiate a bulk password reset within Keycloak, even better.

Again, I haven’t tried or even investigated whether this is practical, but it seems like a reasonable place to start.

On top of my head is to create an user federation plugin and override only the isValid method:
@Override
public boolean isValid(RealmModel realmModel, UserModel userModel, CredentialInput input) {

}

For creating the plugin, you might use this example: https://codesoapbox.dev/keycloak-user-migration/ and implement only the LegacyProvider class’s isValid().

Or you can just use the approach in the example above :slight_smile:

For future reference, we ended up exporting the user data from the old system into a json file that we imported into Keycloak after.

@schu Could you please share the json format which is required to import users

Looking for the same thing here. Does anyone have the right JSON format?

The JSON structure was something like this:

[
  {
    "realm": "myrealm",
    "users": [
      {
        "username": "username",
        "enabled": true,
        "totp": false,
        "emailVerified": true,
        "firstName": "firstName",
        "lastName": "lastName",
        "email": "email",
        "attributes": {
          "locale": [
            "de"
          ]
        },
        "credentials": [
          {
            "type": "password",
            "algorithm": "bcrypt",
            "hashedSaltedValue": "$2y$10$xxxxx"
          }
        ],
        "disableableCredentialTypes": [],
        "requiredActions": [
          "UPDATE_PASSWORD"
        ],
        "notBefore": 0,
        "groups": [
          "/Group"
        ]
      },
      {
        // ... more users
      }
    ]
  }
]

Note that the format could have changed since ('20) and that we use bcrypt.

A test export (Admin Dashboard: Manage → Export) should show the JSON structure.

Hope that helps!

@schu Does this still work in the newest Keycloak?

I’m late to this question, but this is a great extension for importing users from a legacy app. If you have the ability to expose a simple endpoint from the legacy app, it makes migration effortless. Because it operates as a user federation provider, the user’s password is automatically stored as users log in, without any need to try to migrate them. It also supports a great range of roles, groups and attributes. Really great tool.

@schu I have tried this approach with Admin CLI and REST API without success. For both methods I get the response “unable to read contents from stream”. I’m using keycloak 21.0.1. Did you, at some point experience something like this?

1 Like