diff --git a/dataset/dataset-import.sh b/dataset/dataset-import.sh index 855e67d8f..452d9d8fc 100755 --- a/dataset/dataset-import.sh +++ b/dataset/dataset-import.sh @@ -25,7 +25,7 @@ set_environment_variables () { CREATE_TIMEOUT="3600" THREADS="-1" - while getopts ":a:r:n:c:u:e:o:i:p:l:t:C:T:" OPT + while getopts ":a:r:n:c:u:e:o:g:i:p:l:t:C:T:" OPT do case $OPT in a) @@ -49,6 +49,12 @@ set_environment_variables () { o) SESSIONS_COUNT=$OPTARG ;; + g) + HASH_ALGORITHM=$OPTARG + ;; + i) + HASH_ITERATIONS=$OPTARG + ;; p) REALM_PREFIX=$OPTARG ;; @@ -72,11 +78,6 @@ set_environment_variables () { done } -create_realms () { - echo "Creating $1 realm/s with $2 client/s and $3 user/s." - execute_command "create-realms?count=$1&clients-per-realm=$2&users-per-realm=$3&task-timeout=$4&threads-count=$5" -} - create_clients () { echo "Creating $1 client/s in realm $2" execute_command "create-clients?count=$1&realm-name=$2&task-timeout=$3&threads-count=$4" @@ -171,7 +172,7 @@ check_dataset_status () { help () { echo "Dataset import to the local minikube Keycloak application - usage:" - echo "1) create realm/s with clients, users - run -a (action) with or without other arguments: -a create-realms -r 10 -c 100 -u 100 -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'" @@ -189,7 +190,10 @@ main () { echo "Action: [$ACTION] " case "$ACTION" in create-realms) - create_realms $REALM_COUNT $CLIENTS_COUNT $USERS_COUNT $CREATE_TIMEOUT $THREADS + 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 ad1b9ddd5..3120a80d0 100644 --- a/dataset/src/main/java/org/keycloak/benchmark/dataset/DatasetResourceProvider.java +++ b/dataset/src/main/java/org/keycloak/benchmark/dataset/DatasetResourceProvider.java @@ -913,6 +913,14 @@ private void createAndSetRealm(RealmContext context, int index, KeycloakSession realm.setEnabled(true); realm.setRegistrationAllowed(true); realm.setAccessCodeLifespan(60); + 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 323496248..bae36b344 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 @@ -150,6 +150,14 @@ public class DatasetConfig { @QueryParamIntFill(paramName = "client-roles-per-user", defaultValue = 4, operations = { CREATE_REALMS, CREATE_USERS }) private Integer clientRolesPerUser; + // 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 @QueryParamFill(paramName = "events-enabled", defaultValue = "false", operations = { CREATE_REALMS }) private String eventsEnabled; @@ -297,6 +305,14 @@ public Integer getClientRolesPerUser() { return clientRolesPerUser; } + public String getPasswordHashAlgorithm() { + return passwordHashAlgorithm; + } + + public Integer getPasswordHashIterations() { + return passwordHashIterations; + } + public Boolean getEventsEnabled() { return Boolean.valueOf(eventsEnabled); } diff --git a/doc/dataset/modules/ROOT/pages/using-provider.adoc b/doc/dataset/modules/ROOT/pages/using-provider.adoc index a75eaf727..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 - run -a (action) with or without other arguments: -a create-realms -r 10 -c 100 -u 100 -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,10 +168,16 @@ 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`, 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 +.../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.