Learn how to migrate users with censhare standard login into Keycloak by script.


Introduction

For censhare, users who authenticated with standard censhare party entries with login name and password must be migrated to Keycloak users. The password is lost in this scenario since it cannot be deduced from the hashed value stored in the database.

For update installations from censhare 2021.1 or below, these steps are mandatory and must be carried out first, before updating the censhare Server.

Prerequisites

  • JDK 9+ environment to run jshell
  • Terminal access

Migration

Step 1 - Export users

Open the censhare Admin Client. Go to Master data/Users, select the users you want to migrate and click the Export.

As a result, you have a local usergroups.xml  file which is an input file in step 2 below.

Step 2 - Convert data into importable JSON

Create a new JSON file named party-export-.json for each user who is exported in step 1.

From a command line prompt, run:

jshell -class-path /opt/corpus/css/app/common/lib/censhare-support.jar keycloak-user-migration.jsh -R-Dparties=/tmp/usergroups.xml -R-Djsondir=/tmp/
CODE

/tmp/   here is used as an example directory for import and export files. Replace with your respective directory.

Step 3 - Execute Keycloak import

jq  is not strictly required but useful. On macOS, you can install it with  brew install jq.

You need access to a running Keycloak instance and acquire a valid OpenID token.  Execute a command line similar to the following:

TOKEN=$(curl -s -L -X POST http://localhost:8080/auth/realms/censhare/protocol/openid-connect/token \
             -H 'Content-Type: application/x-www-form-urlencoded' \
             --data-urlencode 'client_id=censhare5' \
             --data-urlencode 'grant_type=password' \
             --data-urlencode 'client_secret=YOUR-CENSHARE5-CLIENT-SECRET' \
             --data-urlencode 'scope=openid' \
             --data-urlencode 'username=keycloak-admin' \
             --data-urlencode 'password=secret' | jq -r .access_token)
CODE

Otherwise, just execute the curl command and save the TOKEN for the subsequent calls.

In the example above, the values keycloak-admin/secret are the credentials for the user who was added before and configured in the censhare-Server Keycloak service.

Replace the values for username and password with your actually configured ones.

Import users:

for f in party-export-*.json
do
  echo $f
  curl -X POST http://localhost:8080/auth/admin/realms/censhare/users -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" --data @$f
done
CODE

Keycloak import rejects users if they use the e-mail of any already existing user. In case a user owns several accounts, but has just one email address, turn off Login with Email in the realm settings should be turned off. Otherwise, the users can not be imported, if the same email address is already given to another user.

Check existing users:

curl -s -X GET 'http://localhost:8080/auth/admin/realms/censhare/users' \
     -H "Accept: application/json" \
     -H "Authorization: Bearer $TOKEN" | jq .
CODE

Customizing

You can change the script to your needs. Combine steps 2 and 3 as well as your own additions into a single script if you feel comfortable with the mechanism.

Lowercase in usernames

Keycloak stores usernames and emails in lowercase by design. Mixed-case letters are not supported in Keycloak. 

This might possibly lead to username duplicates.

User migration script

keycloak-user-migration.jsh

Result

Exported users keep their Standard authentication method. To set the authentication method to External, carry out the following step.

Set authentication method to external

For proper user login with Keycloak, the authentication method for users must be set to External in censhare. We provide a script that you can use to change the setting for multiple users at the same time.

  1. Open a terminal and change to the censhare Server directory. 

    cd censhare-Server
    CODE
  2. Enter the following command:

    bin/AdminClient.sh -b convert-users
    CODE
  3. As a result, the number of successfully updated users is displayed:

    <result count="[number-of-users]"/>.
    CODE
  4. To check the result, go to the censhare Admin Client and select Master Data > Users and select a relevant user. 
  5. Under Authentication, External datas synchronization is selected. You may need to reload the data cache or synchronize the server to view the correct result. 

Result

The command changes the authentication method for all migrated users from Standard to External.

  • The user party table in the censhare Server is updated:
    • standard authentication flag -  auth_standard=0 (false)
    • external authentication flag - auth_extern=1 (true)
  • By default, the login is set to censhare.
  • By default, the synchronization level for user data mapping between Keycloak and the censhare Server is set to Basic synchronization (sync_extern=1).

The following users are never updated:

  • censhare user groups
  • system users, for example, render-client
  • users who have no Standard authentication set
  • fixed user names

Customizing

You can customize the script to your needs. For example, you can change the synchronization level for user data mapping or specify user names that should be skipped.

The script is stored in your censhare Server directory under app/modules/migration/convert-users.xml.

<?xml version="1.0" encoding="UTF-8"?>
<cmd
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xe="http://www.censhare.com/xml/3.0.0/xmleditor">

  <xml-info
      title="${title-convert-users}"
      description="${desc-convert-users}"
      knowledge-level="2"
      special-licence="false"
      feature-help=""
      version="1"
      localize="true">
    <property-resources>
      <base url="file:module"/>
      <base url="file:../../common/global"/>
    </property-resources>
  </xml-info>

  <cmd-info
      name="admin.migration.convert-users"
      type="server-action"
      enabled="false">
    <server-action>
      <clients>
        <client type="javaadmin"/>
      </clients>
      <permissions>
        <permission key="app_admin_all"/>
        <permission key="app_admin_configuration"/>
      </permissions>
    </server-action>
  </cmd-info>

  <!-- make invisible in Admin-Client -->
  <!-- <admin-info dialog-id="convert-users" dialog-url="file:config-dialog.xml"/> -->

  <commands currentstep="">
    <command target="ScriptletManager" method="convertUsers" scriptlet="modules.admin.migration.ConvertUsers"/>
  </commands>

  <!-- dynamically filled with number of successful updates on party table, using command slot "result" -->
  <result count="0"/>

  <!-- hard-wired users always skipped:
       - groups (e.g. "_admin")
       - system users
       - users not currently using standard authentication
       sync-extern
       - 0: no sync
       - 1: basic sync
       - 2: full sync
  -->
  <config sync-extern="1">
    <skip>censhare</skip>
  </config>

</cmd>