diff --git a/dataset/dataset-import.sh b/dataset/dataset-import.sh index 439acb86d..b2b5b0b95 100755 --- a/dataset/dataset-import.sh +++ b/dataset/dataset-import.sh @@ -13,14 +13,13 @@ set_environment_variables () { USERS_COUNT="100" EVENTS_COUNT="100" SESSIONS_COUNT="100" - HASH_ITERATIONS="27500" if ( minikube version &>/dev/null ); then KEYCLOAK_URI="https://keycloak-keycloak.$(minikube ip || echo 'unknown').nip.io/realms/master/dataset" fi REALM_PREFIX="realm" STATUS_TIMEOUT="120" - while getopts ":a:r:n:c:u:e:o:i:p:l:t:" OPT + while getopts ":a:r:n:c:u:e:o:g:i:p:l:t:" OPT do case $OPT in a) @@ -44,6 +43,9 @@ set_environment_variables () { o) SESSIONS_COUNT=$OPTARG ;; + g) + HASH_ALGORITHM=$OPTARG + ;; i) HASH_ITERATIONS=$OPTARG ;; @@ -64,11 +66,6 @@ set_environment_variables () { done } -create_realms () { - echo "Creating $1 realm/s with $2 client/s and $3 user/s with $4 password hash iterations." - execute_command "create-realms?count=$1&clients-per-realm=$2&users-per-realm=$3&password-hash-iterations=$4" -} - create_clients () { echo "Creating $1 client/s in realm $2" execute_command "create-clients?count=$1&realm-name=$2" @@ -163,7 +160,7 @@ check_dataset_status () { help () { echo "Dataset import to the local minikube Keycloak application - usage:" - echo "1) create realm/s with clients, users and password hash iterations - run -a (action) with or without other arguments: -a create-realms -r 10 -c 100 -u 100 -i 20000 -l 'https://keycloak.url.com'" + echo "1) create realm/s with clients, users and password hash algorithm & iterations - run -a (action) with or without other arguments: -a create-realms -r 10 -g argon2 -i 5 -c 100 -u 100 -l 'https://keycloak.url.com'" echo "2) create clients in specific realm: -a create-clients -c 100 -n realm-0 -l 'https://keycloak.url.com'" echo "3) create users in specific realm: -a create-users -u 100 -n realm-0 -l 'https://keycloak.url.com'" echo "4) create events in specific realm: -a create-events -e 100 -n realm-0 -l 'https://keycloak.url.com'" @@ -181,7 +178,10 @@ main () { echo "Action: [$ACTION] " case "$ACTION" in create-realms) - create_realms $REALM_COUNT $CLIENTS_COUNT $USERS_COUNT $HASH_ITERATIONS + if [ -z "$HASH_ALGORITHM" ]; then HA_PARAM=""; HASH_ALGORITHM="default"; else HA_PARAM="&password-hash-algorithm=$HASH_ALGORITHM"; fi + if [ -z "$HASH_ITERATIONS" ]; then HI_PARAM=""; HASH_ITERATIONS="default"; else HI_PARAM="&password-hash-iterations=$HASH_ITERATIONS"; fi + echo "Creating $REALM_COUNT realms with $CLIENTS_COUNT clients and $USERS_COUNT users with $HASH_ITERATIONS password-hashing iterations using the $HASH_ALGORITHM algorithm." + execute_command "create-realms?count=$REALM_COUNT&clients-per-realm=$CLIENTS_COUNT&users-per-realm=$USERS_COUNT$HI_PARAM$HA_PARAM" exit 0 ;; create-clients) diff --git a/dataset/src/main/java/org/keycloak/benchmark/dataset/DatasetResourceProvider.java b/dataset/src/main/java/org/keycloak/benchmark/dataset/DatasetResourceProvider.java index fc9ee6ae0..ea896b65f 100644 --- a/dataset/src/main/java/org/keycloak/benchmark/dataset/DatasetResourceProvider.java +++ b/dataset/src/main/java/org/keycloak/benchmark/dataset/DatasetResourceProvider.java @@ -913,7 +913,14 @@ private void createAndSetRealm(RealmContext context, int index, KeycloakSession realm.setEnabled(true); realm.setRegistrationAllowed(true); realm.setAccessCodeLifespan(60); - realm.setPasswordPolicy(PasswordPolicy.parse(session, "hashIterations(" + config.getPasswordHashIterations() + ")")); + PasswordPolicy.Builder b = PasswordPolicy.build(); + if (!config.getPasswordHashAlgorithm().isEmpty()) { // only set if parameter explicitly provided, see QueryParamFill.defaultValue() + b.put("hashAlgorithm", config.getPasswordHashAlgorithm()); + } + if (config.getPasswordHashIterations() != -1) { // only set if parameter explicitly provided, see QueryParamIntFill.defaultValue() + b.put("hashIterations", config.getPasswordHashIterations().toString()); + } + realm.setPasswordPolicy(b.build(session)); if (config.getEventsEnabled()) { realm.setEventsEnabled(true); diff --git a/dataset/src/main/java/org/keycloak/benchmark/dataset/config/DatasetConfig.java b/dataset/src/main/java/org/keycloak/benchmark/dataset/config/DatasetConfig.java index 423481eef..8435ab191 100644 --- a/dataset/src/main/java/org/keycloak/benchmark/dataset/config/DatasetConfig.java +++ b/dataset/src/main/java/org/keycloak/benchmark/dataset/config/DatasetConfig.java @@ -153,8 +153,12 @@ public class DatasetConfig { @QueryParamIntFill(paramName = "client-roles-per-user", defaultValue = 4, operations = { CREATE_REALMS, CREATE_USERS }) private Integer clientRolesPerUser; - // Password policy with the number of password hash iterations. It is 27500 by default - @QueryParamIntFill(paramName = "password-hash-iterations", defaultValue = PasswordPolicy.HASH_ITERATIONS_DEFAULT, operations = { CREATE_REALMS }) + // Password policy with the password hash algorithm. + @QueryParamFill(paramName = "password-hash-algorithm", operations = { CREATE_REALMS }) + private String passwordHashAlgorithm; + + // Password policy with the number of password hash iterations. + @QueryParamIntFill(paramName = "password-hash-iterations", operations = { CREATE_REALMS }) private Integer passwordHashIterations; // Check if eventStorage will be enabled for newly created realms @@ -304,6 +308,10 @@ public Integer getClientRolesPerUser() { return clientRolesPerUser; } + public String getPasswordHashAlgorithm() { + return passwordHashAlgorithm; + } + public Integer getPasswordHashIterations() { return passwordHashIterations; } diff --git a/doc/dataset/modules/ROOT/pages/using-provider.adoc b/doc/dataset/modules/ROOT/pages/using-provider.adoc index a21c788a1..570681c0d 100644 --- a/doc/dataset/modules/ROOT/pages/using-provider.adoc +++ b/doc/dataset/modules/ROOT/pages/using-provider.adoc @@ -31,7 +31,7 @@ You will see these options: ---- Dataset import to the local minikube Keycloak application - usage: -1) create realm/s with clients, users and password hash iterations - run -a (action) with or without other arguments: -a create-realms -r 10 -c 100 -u 100 -h 20000 -l 'https://keycloak.url.com' +1) create realm/s with clients, users and password hash algorithm & iterations - run -a (action) with or without other arguments: -a create-realms -r 10 -g argon2 -i 5 -c 100 -u 100 -l 'https://keycloak.url.com' 2) create clients in specific realm: -a create-clients -c 100 -n realm-0 -l 'https://keycloak.url.com' 3) create users in specific realm: -a create-users -u 100 -n realm-0 -l 'https://keycloak.url.com' 4) create events in specific realm: -a create-events -e 100 -n realm-0 -l 'https://keycloak.url.com' @@ -168,12 +168,18 @@ You can use parameters to remove all realms for example just from `foorealm5` to For change the parameters, take a look at link:{github-files}/dataset/src/main/java/org/keycloak/benchmark/dataset/config/DatasetConfig.java[DataSetConfig class] to see available parameters and default values and which endpoint the particular parameter is applicable. -For example to create realms with prefix `foo` and with just 1000 hash iterations used for the password policy, you can use these parameters: +For example to create realms with prefix `foo` and with just 1000 hash iterations (with the default hashing algorithm) used for the password policy you can use these parameters: ---- .../realms/master/dataset/create-realms?count=10&realm-prefix=foo&password-hash-iterations=1000 ---- +Another example would be, to specify a particular hashing algorithm in combination with the hashing iterations with the below parameters: + +---- +.../realms/master/dataset/create-realms?count=10&realm-prefix=foo&password-hash-algorithm=argon2&password-hash-iterations=1000 +---- + The configuration is written to the server log when HTTP endpoint is triggered, so you can monitor the progress and what parameters were effectively applied. Note that creation of new objects will automatically start from the next available index.