diff --git a/.gitignore b/.gitignore
index 336b753a9..835791c49 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ release.properties
/*.json
/test*
+/exports
diff --git a/docs/FEATURES.md b/docs/FEATURES.md
index ab05ea621..429b354bb 100644
--- a/docs/FEATURES.md
+++ b/docs/FEATURES.md
@@ -57,6 +57,7 @@
| Synchronize user profile | 5.4.0 | Synchronize the user profile configuration defined on the realm configuration |
| Synchronize client-policies | 5.6.0 | Synchronize the client-policies (clientProfiles and clientPolicies) while updating realms |
| Synchronize message bundles | 5.12.0 | Synchronize message bundles defined on the realm configuration |
+| Normalize realm exports | x.x.x | Normalize a full realm export to be more minimal |
# Specificities
diff --git a/docs/NORMALIZE.md b/docs/NORMALIZE.md
new file mode 100644
index 000000000..0df106179
--- /dev/null
+++ b/docs/NORMALIZE.md
@@ -0,0 +1,123 @@
+# Realm normalization
+
+Realm normalization is a feature that is supposed to aid users in migrating from an "unmanaged" Keycloak installation,
+to an installation managed by keycloak-config-cli.
+To achieve this, it uses a full [realm export](https://www.keycloak.org/server/importExport#_exporting_a_specific_realm)
+as an input, and only retains things that deviate from the default
+
+## Usage
+
+To run the normalization, run keycloak-config-cli with the CLI option `--run.operation=NORMALIZE`.
+The default value for this option is `IMPORT`, which will run the regular keycloak-config-cli import.
+
+### Configuration options
+
+| Configuration key | Purpose | Example |
+|--------------------------------------|-----------------------------------------------------------------------------------------------------------------|---------------|
+| run.operation | Tell keycloak-config-cli to normalize, rather than import | NORMALIZE |
+| normalization.files.input-locations | Which realm files to import | See IMPORT.md |
+| normalization.files.output-directory | Where to save output realm files | ./exports/out |
+| normalization.output-format | Whether to output JSON or YAML. Default value is YAML | YAML |
+| normalization.fallback-version | Use this version as a baseline of keycloak version in realm is not available as baseline in keycloak-config-cli | 19.0.3 |
+
+### Unimplemented Features
+- Components:
+ - Currently, keycloak-config-cli will not yet look at the `components` section of the exported JSON
+ - Therefore, some things (like LDAP federation configs and Key providers) are missing from the normalized YAML
+- Users
+ - Users are not currently considered by normalization.
+
+## Missing entries
+keycloak-config-cli will WARN if components that are present in a realm by default are missing from an exported realm.
+An example of such a message is:
+```
+Default realm requiredAction 'webauthn-register-passwordless' was deleted in exported realm. It may be reintroduced during import
+```
+Messages like these will often show up when using keycloak-config-cli to normalize an import from an older version of Keycloak, and compared to a newer baseline.
+In the above case, the Keycloak version is 18.0.3, and the baseline for comparison was 19.0.3.
+Since the webauthn feature was not present (or enabled by default) in the older version, this message is mostly informative.
+If a message like this appears on a component that was *not* deleted or should generally be present, this may indicate a bug in keycloak-config-cli.
+
+## Cleaning of invalid data
+Sometimes, realms of existing installations may contain invalid data, due to faulty migrations, or due to direct interaction with the database,
+rather than the Keycloak API.
+When such problems are found, we attempt to handle them in keycloak-config-cli, or at least notify the user about the existence of these problems.
+
+### SAML Attributes on clients
+While not necessarily invalid, openid-connect clients that were created on older Keycloak versions, will sometimes contain
+SAML-related attributes. These are filtered out by keycloak-config-cli.
+
+### Unused non-top-level Authentication Flows
+Authentication flows in Keycloak are marked as top-level if they are supposed to be available for binding or overrides.
+Authentication flows that are not marked as top-level are used as sub-flows in other authentication flows.
+The normalization process recognizes recursively whether there are authentication flows that are not top level and not used
+by any top level flow, and does not include them in the final result.
+
+A warning message is logged, and you can use the following SQL query to find any authentication flows that are not referenced.
+Note that this query, unlike keycloak-config-cli, is not recursive.
+That means that after deleting an unused flow, additional unused flows may appear after the query is performed again.
+
+```sql
+select flow.alias
+from authentication_flow flow
+ join realm r on flow.realm_id = r.id
+ left join authentication_execution execution on flow.id = execution.auth_flow_id
+where r.name = 'mytest'
+ and execution.id is null
+ and not flow.top_level
+```
+
+### Unused and duplicate Authenticator Configs
+Authenticator Configs are not useful if they are not referenced by at least one authentication execution.
+Therefore, keycloak-config-cli detects unused configurations and does not include them in the resulting output.
+Note that the check for unused configs runs *after* the check for unused flows.
+That means a config will be detected as unused if it is referenced by an execution that is part of a flow that is unused.
+
+A warning message is logged on duplicate or unused configs, and you can use the following SQL query to find any configs
+that are unused:
+
+```sql
+select ac.alias, ac.id
+from authenticator_config ac
+ left join authentication_execution ae on ac.id = ae.auth_config
+ left join authentication_flow af on ae.flow_id = af.id
+ join realm r on ac.realm_id = r.id
+where r.name = 'master' and af.alias is null
+order by ac.alias
+```
+
+And the following query to find duplicates:
+
+```sql
+select alias, count(alias), r.name as realm_name
+from authenticator_config
+ join realm r on realm_id = r.id
+group by alias, r.name
+having count(alias) > 1
+```
+
+If the `af.id` and `af.alias` fields are `null`, the config in question is not in use.
+Note that configs used by unused flows are not marked as unused in the SQL result, as these need to be deleted first
+to become unused.
+After the unused flows (and executions) are deleted, the configs will be marked as unused and can also be deleted.
+
+### Authentication Executions with invalid subflows
+Some keycloak exports have invalid authentication executions that reference a subflow, while also setting an authenticator.
+This is only a valid configuration if the subflow's type is `form-flow`.
+If it is not, then keycloak-config-cli will not import the configuration.
+This will be marked by an ERROR severity message in the log output.
+You can use this SQL query to find offending entries and remediate the configuration errors before continuing.
+
+```sql
+select parent.alias,
+ subflow.alias,
+ execution.alias
+from authentication_execution execution
+ join realm r on execution.realm_id = r.id
+ join authentication_flow parent on execution.flow_id = parent.id
+ join authentication_flow subflow on execution.auth_flow_id = subflow.id
+where execution.auth_flow_id is not null
+ and execution.authenticator is not null
+ and subflow.provider_id <> 'form-flow'
+ and r.name = 'REALMNAME';
+```
diff --git a/pom.xml b/pom.xml
index 8c84fb126..e985c92eb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,6 +74,7 @@
2.1.1
2.4.0
8.0
+ 7.6.3
3.2.5
3.1.1
1.5.3
@@ -129,6 +130,30 @@
import
pom
+
+
+ org.apache.commons
+ commons-text
+ ${commons-text.version}
+
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
+
+
+ net.jodah
+ failsafe
+ ${failsafe.version}
+
+
+
+ org.javers
+ javers-core
+ ${javers.version}
+
@@ -170,12 +195,6 @@
jackson-datatype-jdk8
-
- org.yaml
- snakeyaml
- ${snakeyaml.version}
-
-
org.keycloak
keycloak-admin-client
@@ -209,6 +228,26 @@
${failsafe.version}
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-yaml
+
+
+
+ org.javers
+ javers-core
+
+
+
+ org.yaml
+ snakeyaml
+
+
net.logstash.logback
diff --git a/src/main/java/de/adorsys/keycloak/config/KeycloakConfigApplication.java b/src/main/java/de/adorsys/keycloak/config/KeycloakConfigApplication.java
index 5fa682707..99746d177 100644
--- a/src/main/java/de/adorsys/keycloak/config/KeycloakConfigApplication.java
+++ b/src/main/java/de/adorsys/keycloak/config/KeycloakConfigApplication.java
@@ -20,14 +20,13 @@
package de.adorsys.keycloak.config;
-import de.adorsys.keycloak.config.properties.ImportConfigProperties;
-import de.adorsys.keycloak.config.properties.KeycloakConfigProperties;
+import de.adorsys.keycloak.config.properties.RunConfigProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication(proxyBeanMethods = false)
-@EnableConfigurationProperties({KeycloakConfigProperties.class, ImportConfigProperties.class})
+@EnableConfigurationProperties(RunConfigProperties.class)
public class KeycloakConfigApplication {
public static void main(String[] args) {
// https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-application-exit
diff --git a/src/main/java/de/adorsys/keycloak/config/KeycloakConfigNormalizationRunner.java b/src/main/java/de/adorsys/keycloak/config/KeycloakConfigNormalizationRunner.java
new file mode 100644
index 000000000..44b410b79
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/KeycloakConfigNormalizationRunner.java
@@ -0,0 +1,126 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
+import de.adorsys.keycloak.config.properties.NormalizationConfigProperties;
+import de.adorsys.keycloak.config.properties.NormalizationKeycloakConfigProperties;
+import de.adorsys.keycloak.config.provider.KeycloakExportProvider;
+import de.adorsys.keycloak.config.service.normalize.RealmNormalizationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.ExitCodeGenerator;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.io.FileOutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import static de.adorsys.keycloak.config.properties.NormalizationConfigProperties.OutputFormat.YAML;
+
+@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+@EnableConfigurationProperties({NormalizationConfigProperties.class, NormalizationKeycloakConfigProperties.class})
+public class KeycloakConfigNormalizationRunner implements CommandLineRunner, ExitCodeGenerator {
+
+ private static final Logger logger = LoggerFactory.getLogger(KeycloakConfigNormalizationRunner.class);
+ private static final long START_TIME = System.currentTimeMillis();
+
+ private final RealmNormalizationService normalizationService;
+ private final KeycloakExportProvider exportProvider;
+ private final NormalizationConfigProperties normalizationConfigProperties;
+ private final YAMLMapper yamlMapper;
+ private final ObjectMapper objectMapper;
+ private int exitCode;
+
+ @Autowired
+ public KeycloakConfigNormalizationRunner(RealmNormalizationService normalizationService,
+ KeycloakExportProvider exportProvider,
+ NormalizationConfigProperties normalizationConfigProperties,
+ YAMLMapper yamlMapper,
+ ObjectMapper objectMapper) {
+ this.normalizationService = normalizationService;
+ this.exportProvider = exportProvider;
+ this.normalizationConfigProperties = normalizationConfigProperties;
+ this.yamlMapper = yamlMapper;
+ this.objectMapper = objectMapper;
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+ try {
+ var outputLocation = Paths.get(normalizationConfigProperties.getFiles().getOutputDirectory());
+ if (!Files.exists(outputLocation)) {
+ logger.info("Creating output directory '{}'", outputLocation);
+ Files.createDirectories(outputLocation);
+ }
+ if (!Files.isDirectory(outputLocation)) {
+ logger.error("Output location '{}' is not a directory. Aborting", outputLocation);
+ exitCode = 1;
+ return;
+ }
+
+ for (var exportLocations : exportProvider.readFromLocations().values()) {
+ for (var export : exportLocations.entrySet()) {
+ logger.info("Normalizing file '{}'", export.getKey());
+ for (var realm : export.getValue()) {
+ var normalizedRealm = normalizationService.normalizeRealm(realm);
+ var suffix = normalizationConfigProperties.getOutputFormat() == YAML ? "yaml" : "json";
+ var outputFile = outputLocation.resolve(String.format("%s.%s", normalizedRealm.getRealm(), suffix));
+ try (var os = new FileOutputStream(outputFile.toFile())) {
+ if (normalizationConfigProperties.getOutputFormat() == YAML) {
+ yamlMapper.writeValue(os, normalizedRealm);
+ } else {
+ objectMapper.writeValue(os, normalizedRealm);
+ }
+ }
+ }
+ }
+ }
+ } catch (NullPointerException e) {
+ throw e;
+ } catch (Exception e) {
+ logger.error(e.getMessage());
+
+ exitCode = 1;
+
+ if (logger.isDebugEnabled()) {
+ throw e;
+ }
+ } finally {
+ long totalTime = System.currentTimeMillis() - START_TIME;
+ String formattedTime = new SimpleDateFormat("mm:ss.SSS").format(new Date(totalTime));
+ logger.info("keycloak-config-cli running in {}.", formattedTime);
+ }
+ }
+
+ @Override
+ public int getExitCode() {
+ return exitCode;
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/KeycloakConfigRunner.java b/src/main/java/de/adorsys/keycloak/config/KeycloakConfigRunner.java
index d254adf54..a8fd41002 100644
--- a/src/main/java/de/adorsys/keycloak/config/KeycloakConfigRunner.java
+++ b/src/main/java/de/adorsys/keycloak/config/KeycloakConfigRunner.java
@@ -23,6 +23,7 @@
import de.adorsys.keycloak.config.model.KeycloakImport;
import de.adorsys.keycloak.config.model.RealmImport;
import de.adorsys.keycloak.config.properties.ImportConfigProperties;
+import de.adorsys.keycloak.config.properties.KeycloakConfigProperties;
import de.adorsys.keycloak.config.provider.KeycloakImportProvider;
import de.adorsys.keycloak.config.service.RealmImportService;
import org.slf4j.Logger;
@@ -30,6 +31,8 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.ExitCodeGenerator;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
@@ -39,6 +42,13 @@
import java.util.Map;
@Component
+/*
+ * Spring only considers actual properties set, not default values of @ConfigurationProperties classes.
+ * Therefore, we enable matchIfMissing here, so if there is *no* property set, we consider it an import
+ * for backwards compatibility
+ */
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
+@EnableConfigurationProperties({ImportConfigProperties.class, KeycloakConfigProperties.class})
public class KeycloakConfigRunner implements CommandLineRunner, ExitCodeGenerator {
private static final Logger logger = LoggerFactory.getLogger(KeycloakConfigRunner.class);
private static final long START_TIME = System.currentTimeMillis();
diff --git a/src/main/java/de/adorsys/keycloak/config/configuration/NormalizationConfiguration.java b/src/main/java/de/adorsys/keycloak/config/configuration/NormalizationConfiguration.java
new file mode 100644
index 000000000..21a43888a
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/configuration/NormalizationConfiguration.java
@@ -0,0 +1,137 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.configuration;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
+import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
+import org.javers.core.Javers;
+import org.javers.core.JaversBuilder;
+import org.javers.core.diff.ListCompareAlgorithm;
+import org.javers.core.metamodel.clazz.EntityDefinition;
+import org.javers.core.metamodel.clazz.EntityDefinitionBuilder;
+import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.keycloak.representations.idm.ClientRepresentation;
+import org.keycloak.representations.idm.ClientScopeRepresentation;
+import org.keycloak.representations.idm.ComponentExportRepresentation;
+import org.keycloak.representations.idm.GroupRepresentation;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.UserFederationMapperRepresentation;
+import org.keycloak.representations.idm.UserFederationProviderRepresentation;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class NormalizationConfiguration {
+
+ @Bean
+ public Javers javers() {
+ return commonJavers()
+ .withListCompareAlgorithm(ListCompareAlgorithm.LEVENSHTEIN_DISTANCE)
+ .build();
+ }
+
+ @Bean
+ public Javers unOrderedJavers() {
+ return commonJavers()
+ .withListCompareAlgorithm(ListCompareAlgorithm.AS_SET)
+ .build();
+ }
+
+ @Bean
+ public YAMLMapper yamlMapper() {
+ var ym = new YAMLMapper();
+ ym.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ ym.enable(SerializationFeature.INDENT_OUTPUT);
+ ym.enable(YAMLGenerator.Feature.INDENT_ARRAYS_WITH_INDICATOR);
+ return ym;
+ }
+
+ @Bean
+ public ObjectMapper objectMapper() {
+ var om = new ObjectMapper();
+ om.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ om.enable(SerializationFeature.INDENT_OUTPUT);
+ return om;
+ }
+
+ private JaversBuilder commonJavers() {
+ var realmIgnoredProperties = new ArrayList();
+ realmIgnoredProperties.add("id");
+ realmIgnoredProperties.add("groups");
+ realmIgnoredProperties.add("roles");
+ realmIgnoredProperties.add("defaultRole");
+ realmIgnoredProperties.add("clientProfiles"); //
+ realmIgnoredProperties.add("clientPolicies"); //
+ realmIgnoredProperties.add("users");
+ realmIgnoredProperties.add("federatedUsers");
+ realmIgnoredProperties.add("scopeMappings"); //
+ realmIgnoredProperties.add("clientScopeMappings"); //
+ realmIgnoredProperties.add("clients"); //
+ realmIgnoredProperties.add("clientScopes"); //
+ realmIgnoredProperties.add("userFederationProviders");
+ realmIgnoredProperties.add("userFederationMappers");
+ realmIgnoredProperties.add("identityProviders");
+ realmIgnoredProperties.add("identityProviderMappers");
+ realmIgnoredProperties.add("protocolMappers"); //
+ realmIgnoredProperties.add("components");
+ realmIgnoredProperties.add("authenticationFlows");
+ realmIgnoredProperties.add("authenticatorConfig");
+ realmIgnoredProperties.add("requiredActions");
+ realmIgnoredProperties.add("applicationScopeMappings");
+ realmIgnoredProperties.add("applications");
+ realmIgnoredProperties.add("oauthClients");
+ realmIgnoredProperties.add("clientTemplates");
+ realmIgnoredProperties.add("attributes");
+
+ return JaversBuilder.javers()
+ .registerEntity(new EntityDefinition(RealmRepresentation.class, "realm", realmIgnoredProperties))
+ .registerEntity(new EntityDefinition(ClientRepresentation.class, "clientId",
+ List.of("id", "authorizationSettings", "protocolMappers")))
+ .registerEntity(new EntityDefinition(ProtocolMapperRepresentation.class, "name", List.of("id")))
+ .registerEntity(new EntityDefinition(ClientScopeRepresentation.class, "name", List.of("id", "protocolMappers")))
+ .registerEntity(new EntityDefinition(RoleRepresentation.class, "name", List.of("id", "containerId", "composites", "attributes")))
+ .registerEntity(new EntityDefinition(GroupRepresentation.class, "path", List.of("id", "subGroups", "attributes", "clientRoles")))
+ .registerEntity(new EntityDefinition(AuthenticationFlowRepresentation.class, "alias", List.of("id", "authenticationExecutions")))
+ .registerEntity(new EntityDefinition(IdentityProviderRepresentation.class, "alias", List.of("internalId")))
+ .registerEntity(EntityDefinitionBuilder.entityDefinition(IdentityProviderMapperRepresentation.class)
+ .withIdPropertyNames("name", "identityProviderAlias")
+ .withIgnoredProperties("id").build())
+ .registerEntity(new EntityDefinition(RequiredActionProviderRepresentation.class, "alias"))
+ .registerEntity(new EntityDefinition(UserFederationProviderRepresentation.class, "displayName", List.of("id")))
+ .registerEntity(EntityDefinitionBuilder.entityDefinition(UserFederationMapperRepresentation.class)
+ .withIdPropertyNames("name", "federationProviderDisplayName")
+ .withIgnoredProperties("id").build())
+ .registerEntity(new EntityDefinition(ComponentExportRepresentation.class, "name", List.of("id", "subComponents", "config")));
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/exception/NormalizationException.java b/src/main/java/de/adorsys/keycloak/config/exception/NormalizationException.java
new file mode 100644
index 000000000..6261834b8
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/exception/NormalizationException.java
@@ -0,0 +1,31 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.exception;
+
+public class NormalizationException extends RuntimeException {
+ public NormalizationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public NormalizationException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/factory/UsedAuthenticationFlowWorkaroundFactory.java b/src/main/java/de/adorsys/keycloak/config/factory/UsedAuthenticationFlowWorkaroundFactory.java
index c1aa21641..083871587 100644
--- a/src/main/java/de/adorsys/keycloak/config/factory/UsedAuthenticationFlowWorkaroundFactory.java
+++ b/src/main/java/de/adorsys/keycloak/config/factory/UsedAuthenticationFlowWorkaroundFactory.java
@@ -34,11 +34,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class UsedAuthenticationFlowWorkaroundFactory {
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/model/AuthenticationFlowImport.java b/src/main/java/de/adorsys/keycloak/config/model/AuthenticationFlowImport.java
index 01c046ced..8eba514ba 100644
--- a/src/main/java/de/adorsys/keycloak/config/model/AuthenticationFlowImport.java
+++ b/src/main/java/de/adorsys/keycloak/config/model/AuthenticationFlowImport.java
@@ -23,6 +23,7 @@
import org.apache.commons.lang3.ObjectUtils;
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.io.Serializable;
@@ -34,6 +35,7 @@
*/
@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class AuthenticationFlowImport extends AuthenticationFlowRepresentation {
private static final Comparator COMPARATOR =
new AuthenticationExecutionExportRepresentationComparator();
diff --git a/src/main/java/de/adorsys/keycloak/config/model/RealmImport.java b/src/main/java/de/adorsys/keycloak/config/model/RealmImport.java
index 33ac1e157..a6f86cc19 100644
--- a/src/main/java/de/adorsys/keycloak/config/model/RealmImport.java
+++ b/src/main/java/de/adorsys/keycloak/config/model/RealmImport.java
@@ -25,6 +25,7 @@
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.userprofile.config.UPConfig;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
@@ -32,6 +33,7 @@
import java.util.Map;
@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RealmImport extends RealmRepresentation {
private List authenticationFlowImports;
diff --git a/src/main/java/de/adorsys/keycloak/config/properties/ImportConfigProperties.java b/src/main/java/de/adorsys/keycloak/config/properties/ImportConfigProperties.java
index a9ca479f1..3e84838ba 100644
--- a/src/main/java/de/adorsys/keycloak/config/properties/ImportConfigProperties.java
+++ b/src/main/java/de/adorsys/keycloak/config/properties/ImportConfigProperties.java
@@ -21,6 +21,7 @@
package de.adorsys.keycloak.config.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.validation.annotation.Validated;
import java.util.Collection;
@@ -61,10 +62,14 @@ public class ImportConfigProperties {
@Valid
private final ImportRemoteStateProperties remoteState;
- public ImportConfigProperties(boolean validate, boolean parallel,
- ImportFilesProperties files, ImportVarSubstitutionProperties varSubstitution,
- ImportBehaviorsProperties behaviors, ImportCacheProperties cache, ImportManagedProperties managed,
- ImportRemoteStateProperties remoteState
+ public ImportConfigProperties(@DefaultValue("true") boolean validate,
+ @DefaultValue("false") boolean parallel,
+ @DefaultValue ImportFilesProperties files,
+ @DefaultValue ImportVarSubstitutionProperties varSubstitution,
+ @DefaultValue ImportBehaviorsProperties behaviors,
+ @DefaultValue ImportCacheProperties cache,
+ @DefaultValue ImportManagedProperties managed,
+ @DefaultValue ImportRemoteStateProperties remoteState
) {
this.validate = validate;
this.parallel = parallel;
@@ -158,16 +163,22 @@ public static class ImportManagedProperties {
@NotNull
private final ImportManagedPropertiesValues messageBundles;
- public ImportManagedProperties(ImportManagedPropertiesValues requiredAction, ImportManagedPropertiesValues group,
- ImportManagedPropertiesValues clientScope, ImportManagedPropertiesValues scopeMapping,
- ImportManagedPropertiesValues clientScopeMapping, ImportManagedPropertiesValues component,
- ImportManagedPropertiesValues subComponent, ImportManagedPropertiesValues authenticationFlow,
- ImportManagedPropertiesValues identityProvider, ImportManagedPropertiesValues identityProviderMapper,
- ImportManagedPropertiesValues role, ImportManagedPropertiesValues client,
- ImportManagedPropertiesValues clientAuthorizationResources,
- ImportManagedPropertiesValues clientAuthorizationPolicies,
- ImportManagedPropertiesValues clientAuthorizationScopes,
- ImportManagedPropertiesValues messageBundles) {
+ public ImportManagedProperties(@DefaultValue("FULL") ImportManagedPropertiesValues requiredAction,
+ @DefaultValue("FULL") ImportManagedPropertiesValues group,
+ @DefaultValue("FULL") ImportManagedPropertiesValues clientScope,
+ @DefaultValue("FULL") ImportManagedPropertiesValues scopeMapping,
+ @DefaultValue("FULL") ImportManagedPropertiesValues clientScopeMapping,
+ @DefaultValue("FULL") ImportManagedPropertiesValues component,
+ @DefaultValue("FULL") ImportManagedPropertiesValues subComponent,
+ @DefaultValue("FULL") ImportManagedPropertiesValues authenticationFlow,
+ @DefaultValue("FULL") ImportManagedPropertiesValues identityProvider,
+ @DefaultValue("FULL") ImportManagedPropertiesValues identityProviderMapper,
+ @DefaultValue("FULL") ImportManagedPropertiesValues role,
+ @DefaultValue("FULL") ImportManagedPropertiesValues client,
+ @DefaultValue("FULL") ImportManagedPropertiesValues clientAuthorizationResources,
+ @DefaultValue("FULL") ImportManagedPropertiesValues clientAuthorizationPolicies,
+ @DefaultValue("FULL") ImportManagedPropertiesValues clientAuthorizationScopes,
+ @DefaultValue("FULL") ImportManagedPropertiesValues messageBundles) {
this.requiredAction = requiredAction;
this.group = group;
this.clientScope = clientScope;
@@ -266,7 +277,9 @@ public static class ImportFilesProperties {
@NotNull
private final boolean includeHiddenFiles;
- public ImportFilesProperties(Collection locations, Collection excludes, boolean includeHiddenFiles) {
+ public ImportFilesProperties(Collection locations,
+ @DefaultValue Collection excludes,
+ @DefaultValue("false") boolean includeHiddenFiles) {
this.locations = locations;
this.excludes = excludes;
this.includeHiddenFiles = includeHiddenFiles;
@@ -302,7 +315,11 @@ public static class ImportVarSubstitutionProperties {
@NotNull
private final String suffix;
- public ImportVarSubstitutionProperties(boolean enabled, boolean nested, boolean undefinedIsError, String prefix, String suffix) {
+ public ImportVarSubstitutionProperties(@DefaultValue("false") boolean enabled,
+ @DefaultValue("true") boolean nested,
+ @DefaultValue("true") boolean undefinedIsError,
+ @DefaultValue("$(") String prefix,
+ @DefaultValue(")") String suffix) {
this.enabled = enabled;
this.nested = nested;
this.undefinedIsError = undefinedIsError;
@@ -390,7 +407,8 @@ public static class ImportCacheProperties {
@NotNull
private final String key;
- public ImportCacheProperties(boolean enabled, String key) {
+ public ImportCacheProperties(@DefaultValue("true") boolean enabled,
+ @DefaultValue("default") String key) {
this.enabled = enabled;
this.key = key;
}
@@ -414,7 +432,9 @@ public static class ImportRemoteStateProperties {
@Pattern(regexp = "^[A-Fa-f0-9]+$")
private final String encryptionSalt;
- public ImportRemoteStateProperties(boolean enabled, String encryptionKey, String encryptionSalt) {
+ public ImportRemoteStateProperties(@DefaultValue("true") boolean enabled,
+ String encryptionKey,
+ @DefaultValue("2B521C795FBE2F2425DB150CD3700BA9") String encryptionSalt) {
this.enabled = enabled;
this.encryptionKey = encryptionKey;
this.encryptionSalt = encryptionSalt;
diff --git a/src/main/java/de/adorsys/keycloak/config/properties/KeycloakConfigProperties.java b/src/main/java/de/adorsys/keycloak/config/properties/KeycloakConfigProperties.java
index 0dc8339de..a188db216 100644
--- a/src/main/java/de/adorsys/keycloak/config/properties/KeycloakConfigProperties.java
+++ b/src/main/java/de/adorsys/keycloak/config/properties/KeycloakConfigProperties.java
@@ -21,6 +21,7 @@
package de.adorsys.keycloak.config.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.validation.annotation.Validated;
import java.net.URL;
@@ -69,19 +70,19 @@ public class KeycloakConfigProperties {
private final KeycloakAvailabilityCheck availabilityCheck;
public KeycloakConfigProperties(
- String loginRealm,
- String clientId,
+ @DefaultValue("master") String loginRealm,
+ @DefaultValue("admin-cli") String clientId,
String version,
String url,
- String user,
+ @DefaultValue("admin") String user,
String password,
- String clientSecret,
- String grantType,
- boolean sslVerify,
+ @DefaultValue("") String clientSecret,
+ @DefaultValue("password") String grantType,
+ @DefaultValue("true") boolean sslVerify,
URL httpProxy,
- KeycloakAvailabilityCheck availabilityCheck,
- Duration connectTimeout,
- Duration readTimeout
+ @DefaultValue KeycloakAvailabilityCheck availabilityCheck,
+ @DefaultValue("10s") Duration connectTimeout,
+ @DefaultValue("10s") Duration readTimeout
) {
this.loginRealm = loginRealm;
this.clientId = clientId;
@@ -161,7 +162,9 @@ public static class KeycloakAvailabilityCheck {
private final Duration retryDelay;
@SuppressWarnings("unused")
- public KeycloakAvailabilityCheck(boolean enabled, Duration timeout, Duration retryDelay) {
+ public KeycloakAvailabilityCheck(@DefaultValue("false") boolean enabled,
+ @DefaultValue("120s") Duration timeout,
+ @DefaultValue("2s") Duration retryDelay) {
this.enabled = enabled;
this.timeout = timeout;
this.retryDelay = retryDelay;
diff --git a/src/main/java/de/adorsys/keycloak/config/properties/NormalizationConfigProperties.java b/src/main/java/de/adorsys/keycloak/config/properties/NormalizationConfigProperties.java
new file mode 100644
index 000000000..07a898055
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/properties/NormalizationConfigProperties.java
@@ -0,0 +1,107 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2021 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.bind.DefaultValue;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.Collection;
+
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
+
+@ConfigurationProperties(prefix = "normalization", ignoreUnknownFields = false)
+@Validated
+public class NormalizationConfigProperties {
+
+ @Valid
+ private final NormalizationFilesProperties files;
+
+ private final OutputFormat outputFormat;
+
+ private final String fallbackVersion;
+
+ public NormalizationConfigProperties(@DefaultValue NormalizationFilesProperties files,
+ @DefaultValue("yaml") OutputFormat outputFormat,
+ String fallbackVersion) {
+ this.files = files;
+ this.outputFormat = outputFormat;
+ this.fallbackVersion = fallbackVersion;
+ }
+
+ public NormalizationFilesProperties getFiles() {
+ return files;
+ }
+
+ public OutputFormat getOutputFormat() {
+ return outputFormat;
+ }
+
+ public String getFallbackVersion() {
+ return fallbackVersion;
+ }
+
+ public static class NormalizationFilesProperties {
+
+ @NotNull
+ private final Collection inputLocations;
+
+ @NotNull
+ private final Collection excludes;
+
+ @NotNull
+ private final boolean includeHiddenFiles;
+
+ @NotNull
+ private final String outputDirectory;
+
+ public NormalizationFilesProperties(Collection inputLocations,
+ @DefaultValue Collection excludes,
+ @DefaultValue("false") boolean includeHiddenFiles,
+ String outputDirectory) {
+ this.inputLocations = inputLocations;
+ this.excludes = excludes;
+ this.includeHiddenFiles = includeHiddenFiles;
+ this.outputDirectory = outputDirectory;
+ }
+
+ public Collection getInputLocations() {
+ return inputLocations;
+ }
+
+ public Collection getExcludes() {
+ return excludes;
+ }
+
+ public boolean isIncludeHiddenFiles() {
+ return includeHiddenFiles;
+ }
+
+ public String getOutputDirectory() {
+ return outputDirectory;
+ }
+ }
+
+ public enum OutputFormat {
+ JSON, YAML
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/properties/NormalizationKeycloakConfigProperties.java b/src/main/java/de/adorsys/keycloak/config/properties/NormalizationKeycloakConfigProperties.java
new file mode 100644
index 000000000..c11edb36e
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/properties/NormalizationKeycloakConfigProperties.java
@@ -0,0 +1,47 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2021 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+import jakarta.validation.constraints.NotNull;
+
+/*
+ * Duplicated prefix keycloak. Since only one of the two classes is loaded (depending on configuration) this is fine.
+ * This saves us from having to define a keycloak address for the normalization usage, since we don't actually need to
+ * talk to a keycloak instance, and we only need to know the version.
+ */
+@ConfigurationProperties(prefix = "normalize", ignoreUnknownFields = false)
+@Validated
+public class NormalizationKeycloakConfigProperties {
+
+ @NotNull
+ private final String version;
+
+ public NormalizationKeycloakConfigProperties(String version) {
+ this.version = version;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/properties/RunConfigProperties.java b/src/main/java/de/adorsys/keycloak/config/properties/RunConfigProperties.java
new file mode 100644
index 000000000..ede1713bb
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/properties/RunConfigProperties.java
@@ -0,0 +1,44 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.bind.DefaultValue;
+import org.springframework.validation.annotation.Validated;
+
+@ConfigurationProperties(prefix = "run", ignoreUnknownFields = false)
+@Validated
+public class RunConfigProperties {
+
+ private final Operation operation;
+
+ public RunConfigProperties(@DefaultValue("IMPORT") Operation operation) {
+ this.operation = operation;
+ }
+
+ public Operation getOperation() {
+ return operation;
+ }
+
+ public enum Operation {
+ IMPORT, NORMALIZE
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/provider/BaselineProvider.java b/src/main/java/de/adorsys/keycloak/config/provider/BaselineProvider.java
new file mode 100644
index 000000000..f2722a904
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/provider/BaselineProvider.java
@@ -0,0 +1,111 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.provider;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import de.adorsys.keycloak.config.exception.NormalizationException;
+import de.adorsys.keycloak.config.properties.NormalizationConfigProperties;
+import org.keycloak.representations.idm.ClientRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class BaselineProvider {
+
+ private static final Logger logger = LoggerFactory.getLogger(BaselineProvider.class);
+ private static final String PLACEHOLDER = "REALM_NAME_PLACEHOLDER";
+
+ private final ObjectMapper objectMapper;
+
+ private final String fallbackVersion;
+
+ @Autowired
+ public BaselineProvider(ObjectMapper objectMapper, NormalizationConfigProperties normalizationConfigProperties) {
+ this.objectMapper = objectMapper;
+ this.fallbackVersion = normalizationConfigProperties.getFallbackVersion();
+ }
+
+ public RealmRepresentation getRealm(String version, String realmName) {
+ try (var inputStream = getRealmInputStream(version)) {
+ /*
+ * Replace the placeholder with the realm name to import. This sets some internal values like role names,
+ * baseUrls and redirectUrls so that they don't get picked up as "changes"
+ */
+ var realmString = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8).replace(PLACEHOLDER, realmName);
+ return objectMapper.readValue(realmString, RealmRepresentation.class);
+ } catch (IOException ex) {
+ throw new NormalizationException(String.format("Failed to load baseline realm for version %s", version), ex);
+ }
+ }
+
+ public ClientRepresentation getClient(String version, String clientId) {
+ try (var is = getClientInputStream(version)) {
+ var client = objectMapper.readValue(is, ClientRepresentation.class);
+ client.setClientId(clientId);
+ return client;
+ } catch (IOException ex) {
+ throw new NormalizationException(String.format("Failed to load baseline client for version %s", version), ex);
+ }
+ }
+
+ public InputStream getRealmInputStream(String version) {
+ var inputStream = getClass().getResourceAsStream(String.format("/baseline/%s/realm/realm.json", version));
+ if (inputStream == null) {
+ if (fallbackVersion != null) {
+ logger.warn("Reference realm not found for version {}. Using fallback version {}!", version, fallbackVersion);
+ inputStream = getClass().getResourceAsStream(String.format("/baseline/%s/realm/realm.json", fallbackVersion));
+ if (inputStream == null) {
+ throw new NormalizationException(String.format("Reference realm for version %s does not exist, "
+ + "and fallback version %s does not exist either. Aborting!", version, fallbackVersion));
+ }
+ } else {
+ throw new NormalizationException(String.format("Reference realm for version %s does not exist. Aborting!", version));
+ }
+ }
+ return inputStream;
+ }
+
+ public InputStream getClientInputStream(String version) {
+ var inputStream = getClass().getResourceAsStream(String.format("/baseline/%s/client/client.json", version));
+ if (inputStream == null) {
+ if (fallbackVersion != null) {
+ logger.debug("Reference client not found for version {}. Using fallback version {}!", version, fallbackVersion);
+ inputStream = getClass().getResourceAsStream(String.format("/baseline/%s/client/client.json", fallbackVersion));
+ if (inputStream == null) {
+ throw new NormalizationException(String.format("Reference client for version %s does not exist, "
+ + "and fallback version %s does not exist either. Aborting!", version, fallbackVersion));
+ }
+ } else {
+ throw new NormalizationException(String.format("Reference client for version %s does not exist. Aborting!", version));
+ }
+ }
+ return inputStream;
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/provider/KeycloakExportProvider.java b/src/main/java/de/adorsys/keycloak/config/provider/KeycloakExportProvider.java
new file mode 100644
index 000000000..c64c00a2e
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/provider/KeycloakExportProvider.java
@@ -0,0 +1,232 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2021 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.provider;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import de.adorsys.keycloak.config.exception.InvalidImportException;
+import de.adorsys.keycloak.config.model.ImportResource;
+import de.adorsys.keycloak.config.properties.NormalizationConfigProperties;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.UrlResource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.stereotype.Component;
+import org.springframework.util.PathMatcher;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/*
+ * This class heavily copy pastes code from KeycloakImportProvider. This can probably be reduced quite a bit by moving some code out to a shared class
+ */
+@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class KeycloakExportProvider {
+
+ private static final Logger logger = LoggerFactory.getLogger(KeycloakExportProvider.class);
+
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
+ .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+
+ private final PathMatchingResourcePatternResolver patternResolver;
+
+ private final NormalizationConfigProperties normalizationConfigProperties;
+
+ @Autowired
+ public KeycloakExportProvider(PathMatchingResourcePatternResolver patternResolver,
+ NormalizationConfigProperties normalizationConfigProperties) {
+ this.patternResolver = patternResolver;
+ this.normalizationConfigProperties = normalizationConfigProperties;
+ }
+
+ public Map>> readFromLocations() {
+ Map>> files = new LinkedHashMap<>();
+
+ for (String location : normalizationConfigProperties.getFiles().getInputLocations()) {
+ logger.debug("Loading file location '{}'", location);
+ String resourceLocation = prepareResourceLocation(location);
+
+ Resource[] resources;
+ try {
+ resources = this.patternResolver.getResources(resourceLocation);
+ } catch (IOException e) {
+ throw new InvalidImportException("Unable to proceed location '" + location + "': " + e.getMessage(), e);
+ }
+
+ resources = Arrays.stream(resources).filter(this::filterExcludedResources).toArray(Resource[]::new);
+
+ if (resources.length == 0) {
+ throw new InvalidImportException("No files matching '" + location + "'!");
+ }
+
+ Map> exports = Arrays.stream(resources)
+ .map(this::readResource)
+ .filter(this::filterEmptyResources)
+ .sorted(Map.Entry.comparingByKey())
+ .map(this::readRealms)
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
+ (oldValue, newValue) -> oldValue, LinkedHashMap::new));
+ files.put(location, exports);
+ }
+ return files;
+ }
+
+ private Pair> readRealms(ImportResource resource) {
+ String location = resource.getFilename();
+ String content = resource.getValue();
+
+ if (logger.isTraceEnabled()) {
+ logger.trace(content);
+ }
+
+ List realms;
+ try {
+ realms = readContent(content);
+ } catch (Exception e) {
+ throw new InvalidImportException("Unable to parse file '" + location + "': " + e.getMessage(), e);
+ }
+ return new ImmutablePair<>(location, realms);
+ }
+
+ private List readContent(String content) {
+ List realms = new ArrayList<>();
+
+ Yaml yaml = new Yaml();
+ Iterable yamlDocuments = yaml.loadAll(content);
+
+ for (Object yamlDocument : yamlDocuments) {
+ realms.add(OBJECT_MAPPER.convertValue(yamlDocument, RealmRepresentation.class));
+ }
+ return realms;
+ }
+
+ private String prepareResourceLocation(String location) {
+ String importLocation = location;
+
+ importLocation = importLocation.replaceFirst("^zip:", "jar:");
+
+ // backward compatibility to correct a possible missing prefix "file:" in path
+ if (!importLocation.contains(":")) {
+ importLocation = "file:" + importLocation;
+ }
+ return importLocation;
+ }
+
+ private boolean filterExcludedResources(Resource resource) {
+ if (!resource.isFile()) {
+ return true;
+ }
+
+ File file;
+
+ try {
+ file = resource.getFile();
+ } catch (IOException ignored) {
+ return true;
+ }
+
+ if (file.isDirectory()) {
+ return false;
+ }
+
+ if (!this.normalizationConfigProperties.getFiles().isIncludeHiddenFiles()
+ && (file.isHidden() || FileUtils.hasHiddenAncestorDirectory(file))) {
+ return false;
+ }
+
+ PathMatcher pathMatcher = patternResolver.getPathMatcher();
+ return normalizationConfigProperties.getFiles().getExcludes()
+ .stream()
+ .map(pattern -> pattern.startsWith("**") ? "/" + pattern : pattern)
+ .map(pattern -> !pattern.startsWith("/**") ? "/**" + pattern : pattern)
+ .map(pattern -> !pattern.startsWith("/") ? "/" + pattern : pattern)
+ .noneMatch(pattern -> {
+ boolean match = pathMatcher.match(pattern, file.getPath());
+ if (match) {
+ logger.debug("Excluding resource file '{}' (match {})", file.getPath(), pattern);
+ return true;
+ }
+ return false;
+ });
+ }
+
+ private ImportResource readResource(Resource resource) {
+ logger.debug("Loading file '{}'", resource.getFilename());
+
+ try {
+ resource = setupAuthentication(resource);
+ try (InputStream inputStream = resource.getInputStream()) {
+ return new ImportResource(resource.getURI().toString(), new String(inputStream.readAllBytes(), StandardCharsets.UTF_8));
+ }
+ } catch (IOException e) {
+ throw new InvalidImportException("Unable to proceed resource '" + resource + "': " + e.getMessage(), e);
+ } finally {
+ Authenticator.setDefault(null);
+ }
+ }
+
+ private Resource setupAuthentication(Resource resource) throws IOException {
+ String userInfo;
+
+ try {
+ userInfo = resource.getURL().getUserInfo();
+ } catch (IOException e) {
+ return resource;
+ }
+
+ if (userInfo == null) return resource;
+
+ String[] userInfoSplit = userInfo.split(":");
+
+ if (userInfoSplit.length != 2) return resource;
+
+ Authenticator.setDefault(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(userInfoSplit[0], userInfoSplit[1].toCharArray());
+ }
+ });
+
+ // Mask AuthInfo
+ String location = resource.getURI().toString().replace(userInfo + "@", "***@");
+ return new UrlResource(location);
+ }
+
+ private boolean filterEmptyResources(ImportResource resource) {
+ return !resource.getValue().isEmpty();
+ }
+
+
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/provider/KeycloakImportProvider.java b/src/main/java/de/adorsys/keycloak/config/provider/KeycloakImportProvider.java
index 13506aefa..f8c025ed0 100644
--- a/src/main/java/de/adorsys/keycloak/config/provider/KeycloakImportProvider.java
+++ b/src/main/java/de/adorsys/keycloak/config/provider/KeycloakImportProvider.java
@@ -36,6 +36,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
@@ -54,6 +55,7 @@
import java.util.stream.Collectors;
@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class KeycloakImportProvider {
private final PathMatchingResourcePatternResolver patternResolver;
private final ImportConfigProperties importConfigProperties;
diff --git a/src/main/java/de/adorsys/keycloak/config/provider/KeycloakProvider.java b/src/main/java/de/adorsys/keycloak/config/provider/KeycloakProvider.java
index 20be19461..e76f5e59f 100644
--- a/src/main/java/de/adorsys/keycloak/config/provider/KeycloakProvider.java
+++ b/src/main/java/de/adorsys/keycloak/config/provider/KeycloakProvider.java
@@ -33,6 +33,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.net.URI;
@@ -51,6 +52,7 @@
* to avoid a deadlock.
*/
@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class KeycloakProvider implements AutoCloseable {
private static final Logger logger = LoggerFactory.getLogger(KeycloakProvider.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/AuthenticationFlowRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/AuthenticationFlowRepository.java
index 959f68d12..69989a2ec 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/AuthenticationFlowRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/AuthenticationFlowRepository.java
@@ -32,6 +32,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
@@ -45,6 +46,7 @@
import jakarta.ws.rs.core.Response;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class AuthenticationFlowRepository {
private static final Logger logger = LoggerFactory.getLogger(AuthenticationFlowRepository.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/AuthenticatorConfigRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/AuthenticatorConfigRepository.java
index 10107cbc4..b9849fb46 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/AuthenticatorConfigRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/AuthenticatorConfigRepository.java
@@ -24,12 +24,14 @@
import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class AuthenticatorConfigRepository {
private final AuthenticationFlowRepository authenticationFlowRepository;
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/ClientPoliciesRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/ClientPoliciesRepository.java
index 5fe290ecd..551323d13 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/ClientPoliciesRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/ClientPoliciesRepository.java
@@ -28,9 +28,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientPoliciesRepository {
private static final Logger logger = LoggerFactory.getLogger(ClientPoliciesRepository.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/ClientRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/ClientRepository.java
index 8b89e4a47..e4a159009 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/ClientRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/ClientRepository.java
@@ -35,6 +35,7 @@
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -47,6 +48,7 @@
import jakarta.ws.rs.core.Response;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientRepository {
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/ClientScopeRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/ClientScopeRepository.java
index a5a8bdaa1..239daa9eb 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/ClientScopeRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/ClientScopeRepository.java
@@ -29,6 +29,7 @@
import org.keycloak.representations.idm.ClientScopeRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -40,6 +41,7 @@
import jakarta.ws.rs.core.Response;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientScopeRepository {
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/ComponentRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/ComponentRepository.java
index 388f05073..0ee803767 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/ComponentRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/ComponentRepository.java
@@ -28,6 +28,7 @@
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.representations.idm.ComponentRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.Collections;
@@ -39,6 +40,7 @@
import jakarta.ws.rs.core.Response;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ComponentRepository {
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/ExecutionFlowRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/ExecutionFlowRepository.java
index a806e06a3..8aae2acd1 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/ExecutionFlowRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/ExecutionFlowRepository.java
@@ -31,6 +31,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@@ -42,6 +43,7 @@
import jakarta.ws.rs.core.Response;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ExecutionFlowRepository {
private static final Logger logger = LoggerFactory.getLogger(ExecutionFlowRepository.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/GroupRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/GroupRepository.java
index ad3227c35..662a196f4 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/GroupRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/GroupRepository.java
@@ -32,6 +32,7 @@
import org.keycloak.representations.idm.ManagementPermissionRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -42,6 +43,7 @@
import jakarta.ws.rs.core.Response;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class GroupRepository {
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderMapperRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderMapperRepository.java
index 84563091b..7d557a464 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderMapperRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderMapperRepository.java
@@ -26,6 +26,7 @@
import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -36,6 +37,7 @@
import jakarta.ws.rs.core.Response;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class IdentityProviderMapperRepository {
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderRepository.java
index 14c89315c..f5cd3fcba 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderRepository.java
@@ -28,6 +28,7 @@
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.ManagementPermissionRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -37,6 +38,7 @@
import jakarta.ws.rs.core.Response;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class IdentityProviderRepository {
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/OtpPolicyRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/OtpPolicyRepository.java
index def03b1ec..3f236f7da 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/OtpPolicyRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/OtpPolicyRepository.java
@@ -22,9 +22,11 @@
import org.keycloak.representations.idm.RealmRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class OtpPolicyRepository {
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/RealmRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/RealmRepository.java
index 8a6d44c48..4e2d94220 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/RealmRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/RealmRepository.java
@@ -28,12 +28,16 @@
import org.keycloak.admin.client.resource.RealmsResource;
import org.keycloak.representations.idm.RealmRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
+import java.util.List;
+
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.WebApplicationException;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RealmRepository {
private final KeycloakProvider keycloakProvider;
@@ -106,4 +110,8 @@ public void removeDefaultDefaultClientScope(String realmName, String scopeId) {
public void removeDefaultOptionalClientScope(String realmName, String scopeId) {
getResource(realmName).removeDefaultOptionalClientScope(scopeId);
}
+
+ public List getRealms() {
+ return keycloakProvider.getInstance().realms().findAll();
+ }
}
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/RequiredActionRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/RequiredActionRepository.java
index b6d91be12..d3801dd47 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/RequiredActionRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/RequiredActionRepository.java
@@ -25,6 +25,7 @@
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -36,6 +37,7 @@
* Provides methods to retrieve and store required-actions in your realm
*/
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RequiredActionRepository {
private final AuthenticationFlowRepository authenticationFlowRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/RoleCompositeRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/RoleCompositeRepository.java
index 6eee79b85..7c831c33c 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/RoleCompositeRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/RoleCompositeRepository.java
@@ -26,6 +26,7 @@
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.*;
@@ -33,6 +34,7 @@
import java.util.stream.Collectors;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RoleCompositeRepository {
private final RoleRepository roleRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/RoleRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/RoleRepository.java
index b72397dab..43439ccbf 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/RoleRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/RoleRepository.java
@@ -27,6 +27,7 @@
import org.keycloak.admin.client.resource.*;
import org.keycloak.representations.idm.*;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
@@ -36,6 +37,7 @@
import jakarta.ws.rs.NotFoundException;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RoleRepository {
private final RealmRepository realmRepository;
private final ClientRepository clientRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/ScopeMappingRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/ScopeMappingRepository.java
index 7578129ab..0ae7a37a7 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/ScopeMappingRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/ScopeMappingRepository.java
@@ -26,6 +26,7 @@
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.ScopeMappingRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.Collection;
@@ -33,6 +34,7 @@
import java.util.Objects;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ScopeMappingRepository {
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/StateRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/StateRepository.java
index 212ab611f..38679f63f 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/StateRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/StateRepository.java
@@ -24,6 +24,7 @@
import de.adorsys.keycloak.config.properties.ImportConfigProperties;
import de.adorsys.keycloak.config.util.CryptoUtil;
import org.keycloak.representations.idm.RealmRepresentation;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.text.MessageFormat;
@@ -36,6 +37,7 @@
import static de.adorsys.keycloak.config.util.JsonUtil.toJson;
@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class StateRepository {
private static final int MAX_ATTRIBUTE_LENGTH = 250;
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java
index ceee55568..3d4af81a1 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java
@@ -27,10 +27,12 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class UserProfileRepository {
private static final Logger logger = LoggerFactory.getLogger(UserProfileRepository.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/repository/UserRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/UserRepository.java
index e6ba35d2a..640ece584 100644
--- a/src/main/java/de/adorsys/keycloak/config/repository/UserRepository.java
+++ b/src/main/java/de/adorsys/keycloak/config/repository/UserRepository.java
@@ -28,6 +28,7 @@
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -36,6 +37,7 @@
import jakarta.ws.rs.core.Response;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class UserRepository {
private final RealmRepository realmRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/service/AuthenticationFlowsImportService.java b/src/main/java/de/adorsys/keycloak/config/service/AuthenticationFlowsImportService.java
index 9de2e9cef..a47fa2037 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/AuthenticationFlowsImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/AuthenticationFlowsImportService.java
@@ -35,6 +35,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -53,6 +54,7 @@
* sub-flow: any flow which has the property 'topLevel' set to 'false' and which are related to execution-flows within topLevel-flows
*/
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class AuthenticationFlowsImportService {
private static final Logger logger = LoggerFactory.getLogger(AuthenticationFlowsImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/AuthenticatorConfigImportService.java b/src/main/java/de/adorsys/keycloak/config/service/AuthenticatorConfigImportService.java
index c4a6aa4e5..dc60cba1e 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/AuthenticatorConfigImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/AuthenticatorConfigImportService.java
@@ -29,6 +29,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -39,6 +40,7 @@
import java.util.stream.Stream;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class AuthenticatorConfigImportService {
private static final Logger logger = LoggerFactory.getLogger(AuthenticatorConfigImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/ClientAuthorizationImportService.java b/src/main/java/de/adorsys/keycloak/config/service/ClientAuthorizationImportService.java
index 5532832f3..b3ab46000 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/ClientAuthorizationImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/ClientAuthorizationImportService.java
@@ -45,6 +45,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@@ -60,6 +61,7 @@
@Service
@SuppressWarnings({"java:S1192"})
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientAuthorizationImportService {
private static final Logger logger = LoggerFactory.getLogger(ClientAuthorizationImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/ClientImportService.java b/src/main/java/de/adorsys/keycloak/config/service/ClientImportService.java
index 92b0b26f8..ae59dfcdd 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/ClientImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/ClientImportService.java
@@ -39,6 +39,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.*;
@@ -52,6 +53,7 @@
@Service
@SuppressWarnings({"java:S1192"})
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientImportService {
private static final Logger logger = LoggerFactory.getLogger(ClientImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/ClientPoliciesImportService.java b/src/main/java/de/adorsys/keycloak/config/service/ClientPoliciesImportService.java
index 6522bc24a..337f5089e 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/ClientPoliciesImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/ClientPoliciesImportService.java
@@ -29,9 +29,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientPoliciesImportService {
private static final Logger logger = LoggerFactory.getLogger(ClientPoliciesImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/ClientScopeImportService.java b/src/main/java/de/adorsys/keycloak/config/service/ClientScopeImportService.java
index d242a73da..b93ea5b6d 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/ClientScopeImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/ClientScopeImportService.java
@@ -32,6 +32,7 @@
import org.keycloak.representations.idm.RealmRepresentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -40,6 +41,7 @@
import java.util.function.Consumer;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientScopeImportService {
private static final Logger logger = LoggerFactory.getLogger(ClientScopeImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/ClientScopeMappingImportService.java b/src/main/java/de/adorsys/keycloak/config/service/ClientScopeMappingImportService.java
index 73eea8a76..305bb3aa9 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/ClientScopeMappingImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/ClientScopeMappingImportService.java
@@ -32,6 +32,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -41,6 +42,7 @@
import java.util.function.Predicate;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientScopeMappingImportService {
private static final Logger logger = LoggerFactory.getLogger(ClientScopeMappingImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/ComponentImportService.java b/src/main/java/de/adorsys/keycloak/config/service/ComponentImportService.java
index 586283ab2..0d8bd3042 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/ComponentImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/ComponentImportService.java
@@ -34,11 +34,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ComponentImportService {
private static final Logger logger = LoggerFactory.getLogger(ComponentImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/DefaultGroupsImportService.java b/src/main/java/de/adorsys/keycloak/config/service/DefaultGroupsImportService.java
index e10f91849..3c9aedce2 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/DefaultGroupsImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/DefaultGroupsImportService.java
@@ -26,6 +26,7 @@
import de.adorsys.keycloak.config.repository.RealmRepository;
import org.keycloak.admin.client.resource.RealmResource;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -33,6 +34,7 @@
import jakarta.ws.rs.NotFoundException;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class DefaultGroupsImportService {
private final RealmRepository realmRepository;
private final GroupRepository groupRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/service/ExecutionFlowsImportService.java b/src/main/java/de/adorsys/keycloak/config/service/ExecutionFlowsImportService.java
index de40b5cd6..59c1d1f9b 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/ExecutionFlowsImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/ExecutionFlowsImportService.java
@@ -31,6 +31,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@@ -44,6 +45,7 @@
* Imports executions and execution-flows of existing top-level flows
*/
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ExecutionFlowsImportService {
private static final Logger logger = LoggerFactory.getLogger(ExecutionFlowsImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/GroupImportService.java b/src/main/java/de/adorsys/keycloak/config/service/GroupImportService.java
index e40637026..013a160fe 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/GroupImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/GroupImportService.java
@@ -30,6 +30,7 @@
import org.keycloak.representations.idm.GroupRepresentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -38,6 +39,7 @@
import java.util.stream.Collectors;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class GroupImportService {
private static final Logger logger = LoggerFactory.getLogger(GroupImportService.class);
private static final int LOAD_CREATED_GROUP_MAX_RETRIES = 5;
diff --git a/src/main/java/de/adorsys/keycloak/config/service/IdentityProviderImportService.java b/src/main/java/de/adorsys/keycloak/config/service/IdentityProviderImportService.java
index d2dbfb63e..a444e14a2 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/IdentityProviderImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/IdentityProviderImportService.java
@@ -30,6 +30,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -39,6 +40,7 @@
import static de.adorsys.keycloak.config.properties.ImportConfigProperties.ImportManagedProperties.ImportManagedPropertiesValues;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class IdentityProviderImportService {
private static final Logger logger = LoggerFactory.getLogger(IdentityProviderImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/MessageBundleImportService.java b/src/main/java/de/adorsys/keycloak/config/service/MessageBundleImportService.java
index 5d415ba90..922ebcba2 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/MessageBundleImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/MessageBundleImportService.java
@@ -29,6 +29,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -39,6 +40,7 @@
* Creates and updates message bundles in your realm
*/
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class MessageBundleImportService {
private static final Logger logger = LoggerFactory.getLogger(MessageBundleImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/OtpPolicyImportService.java b/src/main/java/de/adorsys/keycloak/config/service/OtpPolicyImportService.java
index 20ba43f56..f958781ad 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/OtpPolicyImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/OtpPolicyImportService.java
@@ -23,9 +23,11 @@
import de.adorsys.keycloak.config.repository.OtpPolicyRepository;
import org.keycloak.representations.idm.RealmRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class OtpPolicyImportService {
private final OtpPolicyRepository otpPolicyRepository;
diff --git a/src/main/java/de/adorsys/keycloak/config/service/RealmImportService.java b/src/main/java/de/adorsys/keycloak/config/service/RealmImportService.java
index c1af0878e..14c31518c 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/RealmImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/RealmImportService.java
@@ -31,9 +31,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RealmImportService {
static final String[] ignoredPropertiesForRealmImport = new String[]{
"authenticatorConfig",
diff --git a/src/main/java/de/adorsys/keycloak/config/service/RequiredActionsImportService.java b/src/main/java/de/adorsys/keycloak/config/service/RequiredActionsImportService.java
index 602c0db55..1cc001119 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/RequiredActionsImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/RequiredActionsImportService.java
@@ -30,6 +30,7 @@
import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -40,6 +41,7 @@
* Creates and updates required-actions in your realm
*/
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RequiredActionsImportService {
private static final Logger logger = LoggerFactory.getLogger(RequiredActionsImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/RoleImportService.java b/src/main/java/de/adorsys/keycloak/config/service/RoleImportService.java
index 745e7cdb9..447e6815e 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/RoleImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/RoleImportService.java
@@ -34,6 +34,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -44,6 +45,7 @@
import java.util.stream.Collectors;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RoleImportService {
private static final Logger logger = LoggerFactory.getLogger(RoleImportService.class);
private static final String[] propertiesWithDependencies = new String[]{
diff --git a/src/main/java/de/adorsys/keycloak/config/service/ScopeMappingImportService.java b/src/main/java/de/adorsys/keycloak/config/service/ScopeMappingImportService.java
index aab449917..602eca15c 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/ScopeMappingImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/ScopeMappingImportService.java
@@ -30,6 +30,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -38,6 +39,7 @@
import java.util.Set;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ScopeMappingImportService {
private static final Logger logger = LoggerFactory.getLogger(ScopeMappingImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/UserImportService.java b/src/main/java/de/adorsys/keycloak/config/service/UserImportService.java
index 595805013..031409269 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/UserImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/UserImportService.java
@@ -34,6 +34,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@@ -42,6 +43,7 @@
import java.util.stream.Collectors;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class UserImportService {
private static final Logger logger = LoggerFactory.getLogger(UserImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/UserProfileImportService.java b/src/main/java/de/adorsys/keycloak/config/service/UserProfileImportService.java
index 48ee64525..95fac2fa7 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/UserProfileImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/UserProfileImportService.java
@@ -26,9 +26,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class UserProfileImportService {
private static final Logger logger = LoggerFactory.getLogger(UserProfileImportService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/checksum/ChecksumService.java b/src/main/java/de/adorsys/keycloak/config/service/checksum/ChecksumService.java
index 87bd7b21a..2cd98d18d 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/checksum/ChecksumService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/checksum/ChecksumService.java
@@ -31,6 +31,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.text.MessageFormat;
@@ -38,6 +39,7 @@
import java.util.Objects;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ChecksumService {
private static final Logger logger = LoggerFactory.getLogger(ChecksumService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/AttributeNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/AttributeNormalizationService.java
new file mode 100644
index 000000000..267faab0d
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/AttributeNormalizationService.java
@@ -0,0 +1,96 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.*;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class AttributeNormalizationService {
+
+ private final Javers unOrderedJavers;
+
+ public AttributeNormalizationService(Javers unOrderedJavers) {
+ this.unOrderedJavers = unOrderedJavers;
+ }
+
+ public Map normalizeStringAttributes(Map exportedAttributes, Map baselineAttributes) {
+ var exportedOrEmpty = getNonNull(exportedAttributes);
+ var baselineOrEmpty = getNonNull(baselineAttributes);
+ var normalizedAttributes = new HashMap();
+ for (var entry : baselineOrEmpty.entrySet()) {
+ var attributeName = entry.getKey();
+ var baselineAttribute = entry.getValue();
+ var exportedAttribute = exportedOrEmpty.remove(attributeName);
+
+ if (!Objects.equals(baselineAttribute, exportedAttribute)) {
+ normalizedAttributes.put(attributeName, exportedAttribute);
+ }
+ }
+ normalizedAttributes.putAll(exportedOrEmpty);
+ return normalizedAttributes.isEmpty() ? null : normalizedAttributes;
+ }
+
+ public Map> normalizeListAttributes(Map> exportedAttributes,
+ Map> baselineAttributes) {
+ var exportedOrEmpty = getNonNull(exportedAttributes);
+ var baselineOrEmpty = getNonNull(baselineAttributes);
+ var normalizedAttributes = new HashMap>();
+ for (var entry : baselineOrEmpty.entrySet()) {
+ var attributeName = entry.getKey();
+ var baselineAttribute = entry.getValue();
+ var exportedAttribute = exportedOrEmpty.remove(attributeName);
+
+ if (unOrderedJavers.compareCollections(baselineAttribute, exportedAttribute, String.class).hasChanges()) {
+ normalizedAttributes.put(attributeName, exportedAttribute);
+ }
+ }
+ normalizedAttributes.putAll(exportedOrEmpty);
+ return normalizedAttributes.isEmpty() ? null : normalizedAttributes;
+ }
+
+ public boolean listAttributesChanged(Map> exportedAttributes, Map> baselineAttributes) {
+ var exportedOrEmpty = getNonNull(exportedAttributes);
+ var baselineOrEmpty = getNonNull(baselineAttributes);
+
+ if (!Objects.equals(exportedOrEmpty.keySet(), baselineOrEmpty.keySet())) {
+ return true;
+ }
+
+ for (var entry : baselineOrEmpty.entrySet()) {
+ if (unOrderedJavers.compareCollections(entry.getValue(),
+ exportedOrEmpty.get(entry.getKey()), String.class).hasChanges()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/AuthFlowNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/AuthFlowNormalizationService.java
new file mode 100644
index 000000000..6f00051a4
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/AuthFlowNormalizationService.java
@@ -0,0 +1,238 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.keycloak.representations.idm.AbstractAuthenticationExecutionRepresentation;
+import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
+import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+import static java.util.function.Predicate.not;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class AuthFlowNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(AuthFlowNormalizationService.class);
+
+ private final Javers unOrderedJavers;
+
+ public AuthFlowNormalizationService(Javers unOrderedJavers) {
+ this.unOrderedJavers = unOrderedJavers;
+ }
+
+ public List normalizeAuthFlows(List exportedAuthFlows,
+ List baselineAuthFlows) {
+ var exportedFiltered = filterBuiltIn(exportedAuthFlows);
+ var baselineFiltered = filterBuiltIn(baselineAuthFlows);
+
+ Map exportedMap = exportedFiltered.stream()
+ .collect(Collectors.toMap(AuthenticationFlowRepresentation::getAlias, Function.identity()));
+ Map baselineMap = baselineFiltered.stream()
+ .collect(Collectors.toMap(AuthenticationFlowRepresentation::getAlias, Function.identity()));
+
+ List normalizedFlows = new ArrayList<>();
+ for (var entry : baselineMap.entrySet()) {
+ var alias = entry.getKey();
+ var exportedFlow = exportedMap.remove(alias);
+ if (exportedFlow == null) {
+ logger.warn("Default realm authentication flow '{}' was deleted in exported realm. It may be reintroduced during import", alias);
+ continue;
+ }
+ var baselineFlow = entry.getValue();
+ var diff = unOrderedJavers.compare(baselineFlow, exportedFlow);
+
+ if (diff.hasChanges() || executionsChanged(exportedFlow.getAuthenticationExecutions(), baselineFlow.getAuthenticationExecutions())) {
+ normalizedFlows.add(exportedFlow);
+ }
+ }
+ normalizedFlows.addAll(exportedMap.values());
+ for (var flow : normalizedFlows) {
+ flow.setId(null);
+ }
+ normalizedFlows = filterUnusedNonTopLevel(normalizedFlows);
+ detectBrokenAuthenticationFlows(normalizedFlows);
+ return normalizedFlows.isEmpty() ? null : normalizedFlows;
+ }
+
+ public void detectBrokenAuthenticationFlows(List flows) {
+ var flowsByAlias = flows.stream().collect(Collectors.toMap(AuthenticationFlowRepresentation::getAlias, Function.identity()));
+ for (var flow : flows) {
+ for (var execution : flow.getAuthenticationExecutions()) {
+ var flowAlias = execution.getFlowAlias();
+ var authenticator = execution.getAuthenticator();
+
+ if (flowAlias != null && authenticator != null) {
+ var referencedFlow = flowsByAlias.get(flowAlias);
+ if (!"form-flow".equals(referencedFlow.getProviderId())) {
+ logger.error("An execution of flow '{}' defines an authenticator and references the sub-flow '{}'."
+ + " This is only possible if the sub-flow is of type 'form-flow', but it is of type '{}'."
+ + " keycloak-config-cli will refuse to import this flow. See NORMALIZE.md for more information.",
+ flow.getAlias(), flowAlias, referencedFlow.getProviderId());
+ }
+ }
+ }
+ }
+
+ }
+
+ public List normalizeAuthConfig(List configs,
+ List flows) {
+ var flowsOrEmpty = getNonNull(flows);
+ // Find out which configs are actually used by the normalized flows
+ var usedConfigs = flowsOrEmpty.stream()
+ .map(AuthenticationFlowRepresentation::getAuthenticationExecutions)
+ .map(l -> l.stream()
+ .map(AbstractAuthenticationExecutionRepresentation::getAuthenticatorConfig)
+ .collect(Collectors.toList())).flatMap(Collection::stream)
+ .collect(Collectors.toSet());
+
+ var configOrEmpty = getNonNull(configs);
+ // Only return configs that are used
+ var filteredConfigs = configOrEmpty.stream()
+ .filter(acr -> usedConfigs.contains(acr.getAlias())).collect(Collectors.toList());
+
+ var duplicates = new HashSet();
+ var seen = new HashSet();
+ for (var config : filteredConfigs) {
+ config.setId(null);
+ if (seen.contains(config.getAlias())) {
+ duplicates.add(config.getAlias());
+ } else {
+ seen.add(config.getAlias());
+ }
+ }
+
+ if (!duplicates.isEmpty()) {
+ logger.warn("The following authenticator configs are duplicates: {}. "
+ + "Check NORMALIZE.md for an SQL query to find the offending entries in your database!", duplicates);
+ }
+
+ if (configs.size() != filteredConfigs.size()) {
+ logger.warn("Some authenticator configs are unused. Check NORMALIZE.md for an SQL query to find the offending entries in your database!");
+ }
+ return filteredConfigs.isEmpty() ? null : filteredConfigs;
+ }
+
+ private List filterBuiltIn(List flows) {
+ if (flows == null) {
+ return new ArrayList<>();
+ }
+ return flows.stream().filter(not(AuthenticationFlowRepresentation::isBuiltIn)).collect(Collectors.toList());
+ }
+
+ private List filterUnusedNonTopLevel(List flows) {
+ // Assume all top level flows are used
+ var usedFlows = flows.stream().filter(AuthenticationFlowRepresentation::isTopLevel).collect(Collectors.toList());
+ var potentialUnused = flows.stream().filter(not(AuthenticationFlowRepresentation::isTopLevel))
+ .collect(Collectors.toMap(AuthenticationFlowRepresentation::getAlias, Function.identity()));
+ var toCheck = new ArrayList<>(usedFlows);
+ while (!toCheck.isEmpty()) {
+ var toRemove = new ArrayList();
+ for (var flow : toCheck) {
+ for (var execution : flow.getAuthenticationExecutions()) {
+ var alias = execution.getFlowAlias();
+ if (alias != null && potentialUnused.containsKey(alias)) {
+ toRemove.add(alias);
+ }
+ }
+ }
+ toCheck.clear();
+ for (var alias : toRemove) {
+ toCheck.add(potentialUnused.remove(alias));
+ }
+ usedFlows.addAll(toCheck);
+ }
+ if (usedFlows.size() != flows.size()) {
+ logger.warn("The following authentication flows are unused: {}. "
+ + "Check NORMALIZE.md for an SQL query to find the offending entries in your database!", potentialUnused.keySet());
+ }
+ return usedFlows;
+ }
+
+ public boolean executionsChanged(List exportedExecutions,
+ List baselineExecutions) {
+ if (exportedExecutions == null && baselineExecutions != null) {
+ return true;
+ }
+
+ if (exportedExecutions != null && baselineExecutions == null) {
+ return true;
+ }
+
+ if (exportedExecutions == null) {
+ return false;
+ }
+
+ if (exportedExecutions.size() != baselineExecutions.size()) {
+ return true;
+ }
+
+ exportedExecutions.sort(Comparator.comparing(AbstractAuthenticationExecutionRepresentation::getPriority));
+ baselineExecutions.sort(Comparator.comparing(AbstractAuthenticationExecutionRepresentation::getPriority));
+
+ for (int i = 0; i < exportedExecutions.size(); i++) {
+ if (executionChanged(exportedExecutions.get(i), baselineExecutions.get(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean executionChanged(AuthenticationExecutionExportRepresentation exportedExecution,
+ AuthenticationExecutionExportRepresentation baselineExecution) {
+ if (!Objects.equals(exportedExecution.getAuthenticatorConfig(), baselineExecution.getAuthenticatorConfig())) {
+ return true;
+ }
+ if (!Objects.equals(exportedExecution.getAuthenticator(), baselineExecution.getAuthenticator())) {
+ return true;
+ }
+ if (!Objects.equals(exportedExecution.isAuthenticatorFlow(), baselineExecution.isAuthenticatorFlow())) {
+ return true;
+ }
+ if (!Objects.equals(exportedExecution.getRequirement(), baselineExecution.getRequirement())) {
+ return true;
+ }
+ if (!Objects.equals(exportedExecution.getPriority(), baselineExecution.getPriority())) {
+ return true;
+ }
+ if (!Objects.equals(exportedExecution.getFlowAlias(), baselineExecution.getFlowAlias())) {
+ return true;
+ }
+ return !Objects.equals(exportedExecution.isUserSetupAllowed(), baselineExecution.isUserSetupAllowed());
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/ClientNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/ClientNormalizationService.java
new file mode 100644
index 000000000..e36b40063
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/ClientNormalizationService.java
@@ -0,0 +1,169 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import de.adorsys.keycloak.config.provider.BaselineProvider;
+import de.adorsys.keycloak.config.util.JaversUtil;
+import org.javers.core.Javers;
+import org.javers.core.diff.changetype.PropertyChange;
+import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.keycloak.representations.idm.ClientRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class ClientNormalizationService {
+
+ private static final Set SAML_ATTRIBUTES = Set.of("saml_signature_canonicalization_method", "saml.onetimeuse.condition",
+ "saml_name_id_format", "saml.authnstatement", "saml.server.signature.keyinfo$xmlSigKeyInfoKeyNameTransformer",
+ "saml_force_name_id_format", "saml.artifact.binding", "saml.artifact.binding.identifier", "saml.server.signature", "saml.encrypt",
+ "saml.assertion.signature", "saml.allow.ecp.flow", "saml.signing.private.key", "saml.force.name.id.format", "saml.client.signature",
+ "saml.signature.algorithm", "saml.signing.certificate", "saml.server.signature.keyinfo.ext", "saml.multivalued.roles",
+ "saml.force.post.binding");
+
+ private static final Logger logger = LoggerFactory.getLogger(ClientNormalizationService.class);
+ private final Javers unOrderedJavers;
+ private final BaselineProvider baselineProvider;
+ private final JaversUtil javersUtil;
+
+ public ClientNormalizationService(Javers unOrderedJavers,
+ BaselineProvider baselineProvider,
+ JaversUtil javersUtil) {
+ this.unOrderedJavers = unOrderedJavers;
+ this.baselineProvider = baselineProvider;
+ this.javersUtil = javersUtil;
+ }
+
+ public List normalizeClients(RealmRepresentation exportedRealm, RealmRepresentation baselineRealm) {
+ var exportedOrEmpty = getNonNull(exportedRealm.getClients());
+ var baselineOrEmpty = getNonNull(baselineRealm.getClients());
+ var exportedClientMap = new HashMap();
+ for (var exportedClient : exportedOrEmpty) {
+ exportedClientMap.put(exportedClient.getClientId(), exportedClient);
+ }
+
+ var baselineClientMap = new HashMap();
+ var clients = new ArrayList();
+ for (var baselineRealmClient : baselineOrEmpty) {
+ var clientId = baselineRealmClient.getClientId();
+ baselineClientMap.put(clientId, baselineRealmClient);
+ var exportedClient = exportedClientMap.get(clientId);
+ if (exportedClient == null) {
+ logger.warn("Default realm client '{}' was deleted in exported realm. It may be reintroduced during import!", clientId);
+ /*
+ * Here we need to define a configuration parameter: If we want the import *not* to reintroduce default clients that were
+ * deleted, we need to add *all* clients, not just default clients to the dump. Then during import, set the mode that
+ * makes clients fully managed, so that *only* clients that are in the dump end up in the realm
+ */
+ continue;
+ }
+ if (clientChanged(exportedClient, baselineRealmClient)) {
+ // We know the client has changed in some way. Now, compare it to a default client to minimize it
+ clients.add(normalizeClient(exportedClient, exportedRealm.getKeycloakVersion(), exportedRealm));
+ }
+ }
+
+ // Now iterate over all the clients that are *not* default clients
+ for (Map.Entry e : exportedClientMap.entrySet()) {
+ if (!baselineClientMap.containsKey(e.getKey())) {
+ clients.add(normalizeClient(e.getValue(), exportedRealm.getKeycloakVersion(), exportedRealm));
+ }
+ }
+ return clients;
+ }
+
+ public ClientRepresentation normalizeClient(ClientRepresentation client, String keycloakVersion, RealmRepresentation exportedRealm) {
+ var clientId = client.getClientId();
+ var baselineClient = baselineProvider.getClient(keycloakVersion, clientId);
+ var diff = unOrderedJavers.compare(baselineClient, client);
+ var normalizedClient = new ClientRepresentation();
+ for (var change : diff.getChangesByType(PropertyChange.class)) {
+ javersUtil.applyChange(normalizedClient, change);
+ }
+
+ // Always include protocol, even if it's the default "openid-connect"
+ normalizedClient.setProtocol(client.getProtocol());
+ var mappers = client.getProtocolMappers();
+ normalizedClient.setProtocolMappers(mappers);
+ if (mappers != null) {
+ for (var mapper : mappers) {
+ mapper.setId(null);
+ }
+ }
+ normalizedClient.setAuthorizationSettings(client.getAuthorizationSettings());
+ normalizedClient.setClientId(clientId);
+
+ // Older versions of keycloak include SAML attributes even in OIDC clients. Ignore these.
+ if (normalizedClient.getProtocol().equals("openid-connect") && normalizedClient.getAttributes() != null) {
+ normalizedClient.getAttributes().keySet().removeIf(SAML_ATTRIBUTES::contains);
+ }
+
+ if (normalizedClient.getAuthenticationFlowBindingOverrides() != null) {
+ var overrides = new HashMap();
+ var flows = exportedRealm.getAuthenticationFlows().stream()
+ .collect(Collectors.toMap(AuthenticationFlowRepresentation::getId, AuthenticationFlowRepresentation::getAlias));
+ for (var entry : normalizedClient.getAuthenticationFlowBindingOverrides().entrySet()) {
+ var id = entry.getValue();
+ overrides.put(entry.getKey(), flows.get(id));
+ }
+ normalizedClient.setAuthenticationFlowBindingOverrides(overrides);
+ }
+ normalizedClient.setPublicClient(client.isPublicClient());
+ return normalizedClient;
+ }
+
+ public boolean clientChanged(ClientRepresentation exportedClient, ClientRepresentation baselineClient) {
+ var diff = unOrderedJavers.compare(baselineClient, exportedClient);
+ if (diff.hasChanges()) {
+ return true;
+ }
+ if (protocolMappersChanged(exportedClient.getProtocolMappers(), baselineClient.getProtocolMappers())) {
+ return true;
+ }
+ return authorizationSettingsChanged(exportedClient.getAuthorizationSettings(), baselineClient.getAuthorizationSettings());
+ }
+
+ public boolean protocolMappersChanged(List exportedMappers, List baselineMappers) {
+ // CompareCollections doesn't handle nulls gracefully
+ return unOrderedJavers.compareCollections(getNonNull(baselineMappers), getNonNull(exportedMappers), ProtocolMapperRepresentation.class)
+ .hasChanges();
+ }
+
+ public boolean authorizationSettingsChanged(ResourceServerRepresentation exportedSettings, ResourceServerRepresentation baselineSettings) {
+ return unOrderedJavers.compare(baselineSettings, exportedSettings).hasChanges();
+ }
+
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/ClientPolicyNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/ClientPolicyNormalizationService.java
new file mode 100644
index 000000000..823e13257
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/ClientPolicyNormalizationService.java
@@ -0,0 +1,49 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2023 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.keycloak.representations.idm.ClientPoliciesRepresentation;
+import org.keycloak.representations.idm.ClientProfilesRepresentation;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class ClientPolicyNormalizationService {
+
+ public ClientPoliciesRepresentation normalizePolicies(ClientPoliciesRepresentation exportedPolicies,
+ ClientPoliciesRepresentation baselinePolicies) {
+ var policies = exportedPolicies.getPolicies();
+ if (policies == null || policies.isEmpty()) {
+ return null;
+ }
+ return exportedPolicies;
+ }
+
+ public ClientProfilesRepresentation normalizeProfiles(ClientProfilesRepresentation exportedProfiles,
+ ClientProfilesRepresentation baselineProfiles) {
+ var profiles = exportedProfiles.getProfiles();
+ if (profiles == null || profiles.isEmpty()) {
+ return null;
+ }
+ return exportedProfiles;
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/ClientScopeNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/ClientScopeNormalizationService.java
new file mode 100644
index 000000000..3825beee2
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/ClientScopeNormalizationService.java
@@ -0,0 +1,107 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.keycloak.representations.idm.ClientScopeRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class ClientScopeNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(ClientScopeNormalizationService.class);
+
+ private final Javers unOrderedJavers;
+
+ public ClientScopeNormalizationService(Javers unOrderedJavers) {
+ this.unOrderedJavers = unOrderedJavers;
+ }
+
+ public List normalizeClientScopes(List exportedScopes,
+ List baselineScopes) {
+ var exportedOrEmpty = getNonNull(exportedScopes);
+ var baselineOrEmpty = getNonNull(baselineScopes);
+
+ var exportedMap = exportedOrEmpty.stream().collect(Collectors.toMap(ClientScopeRepresentation::getName,
+ Function.identity()));
+ var baselineMap = baselineOrEmpty.stream().collect(Collectors.toMap(ClientScopeRepresentation::getName,
+ Function.identity()));
+
+ var normalizedScopes = new ArrayList();
+ for (var entry : baselineMap.entrySet()) {
+ var scopeName = entry.getKey();
+ var baselineScope = entry.getValue();
+ var exportedScope = exportedMap.remove(scopeName);
+
+ if (exportedScope == null) {
+ logger.warn("Default realm clientScope '{}' was deleted in exported realm. It may be reintroduced during import!", scopeName);
+ continue;
+ }
+
+ if (clientScopeChanged(exportedScope, baselineScope)) {
+ normalizedScopes.add(exportedScope);
+ }
+ }
+ normalizedScopes.addAll(exportedMap.values());
+
+ normalizeList(normalizedScopes);
+ return normalizedScopes.isEmpty() ? null : normalizedScopes;
+ }
+
+ private static void normalizeList(ArrayList normalizedScopes) {
+ for (var scope : normalizedScopes) {
+ scope.setId(null);
+ if (scope.getProtocolMappers() != null) {
+ for (var mapper : scope.getProtocolMappers()) {
+ mapper.setId(null);
+ }
+ if (scope.getProtocolMappers().isEmpty()) {
+ scope.setProtocolMappers(null);
+ }
+ }
+ }
+ }
+
+ public boolean clientScopeChanged(ClientScopeRepresentation exportedScope, ClientScopeRepresentation baselineScope) {
+ if (unOrderedJavers.compare(baselineScope, exportedScope).hasChanges()) {
+ return true;
+ }
+
+ return protocolMappersChanged(exportedScope.getProtocolMappers(), baselineScope.getProtocolMappers());
+ }
+
+ public boolean protocolMappersChanged(List exportedMappers, List baselineMappers) {
+ return unOrderedJavers.compareCollections(getNonNull(baselineMappers), getNonNull(exportedMappers),
+ ProtocolMapperRepresentation.class).hasChanges();
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/ComponentNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/ComponentNormalizationService.java
new file mode 100644
index 000000000..274fa709f
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/ComponentNormalizationService.java
@@ -0,0 +1,90 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.keycloak.common.util.MultivaluedHashMap;
+import org.keycloak.representations.idm.ComponentExportRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class ComponentNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(ComponentNormalizationService.class);
+
+ private final Javers unOrderedJavers;
+
+ public ComponentNormalizationService(Javers unOrderedJavers) {
+ this.unOrderedJavers = unOrderedJavers;
+ }
+
+ public MultivaluedHashMap
+ normalizeComponents(MultivaluedHashMap exportedComponents,
+ MultivaluedHashMap baselineComponents) {
+ var exportedOrEmpty = getNonNull(exportedComponents);
+ var baselineOrEmpty = getNonNull(baselineComponents);
+
+ var normalizedMap = new MultivaluedHashMap();
+ for (var entry : baselineOrEmpty.entrySet()) {
+ var componentClass = entry.getKey();
+
+ var exportedList = exportedOrEmpty.remove(componentClass);
+
+ if (exportedList == null) {
+ logger.warn("Default realm component '{}' was deleted in exported realm. It may be reintroduced during import!", componentClass);
+ continue;
+ }
+ var baselineList = entry.getValue();
+ var normalizedList = normalizeList(exportedList, baselineList, componentClass);
+ normalizedMap.put(componentClass, normalizedList);
+ }
+ normalizedMap.putAll(exportedOrEmpty);
+ //var toRemove = new HashSet();
+ for (var entry : normalizedMap.entrySet()) {
+ var componentList = entry.getValue();
+ for (var component : componentList) {
+ normalizeEntry(component);
+ }
+ }
+ return new MultivaluedHashMap<>();
+ }
+
+ public List normalizeList(List exportedComponents,
+ List baselineComponents,
+ String componentClass) {
+ return List.of();
+ }
+
+ public void normalizeEntry(ComponentExportRepresentation component) {
+ component.setId(null);
+ if (component.getConfig() != null && component.getConfig().isEmpty()) {
+ component.setConfig(null);
+ }
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/GroupNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/GroupNormalizationService.java
new file mode 100644
index 000000000..10cf28c6b
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/GroupNormalizationService.java
@@ -0,0 +1,141 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.keycloak.representations.idm.GroupRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class GroupNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(GroupNormalizationService.class);
+
+ private final Javers unOrderedJavers;
+ private final AttributeNormalizationService attributeNormalizationService;
+
+ public GroupNormalizationService(Javers unOrderedJavers,
+ AttributeNormalizationService attributeNormalizationService) {
+ this.unOrderedJavers = unOrderedJavers;
+ this.attributeNormalizationService = attributeNormalizationService;
+ }
+
+ public List normalizeGroups(List exportedGroups, List baselineGroups) {
+ var exportedOrEmpty = getNonNull(exportedGroups);
+ var baselineOrEmpty = getNonNull(baselineGroups);
+ var exportedGroupsMap = exportedOrEmpty.stream()
+ .collect(Collectors.toMap(GroupRepresentation::getPath, Function.identity()));
+ var baselineGroupsMap = baselineOrEmpty.stream()
+ .collect(Collectors.toMap(GroupRepresentation::getPath, Function.identity()));
+
+ var normalizedGroups = new ArrayList();
+ for (var entry : baselineGroupsMap.entrySet()) {
+ var groupPath = entry.getKey();
+ var exportedGroup = exportedGroupsMap.remove(groupPath);
+ if (exportedGroup == null) {
+ logger.warn("Default realm group '{}' was deleted in exported realm. It may be reintroduced during import", groupPath);
+ continue;
+ }
+ var baselineGroup = entry.getValue();
+ var diff = unOrderedJavers.compare(baselineGroup, exportedGroup);
+
+ if (diff.hasChanges() || subGroupsChanged(exportedGroup, baselineGroup)
+ || attributeNormalizationService.listAttributesChanged(exportedGroup.getAttributes(), baselineGroup.getAttributes())
+ || attributeNormalizationService.listAttributesChanged(exportedGroup.getClientRoles(), baselineGroup.getClientRoles())) {
+ normalizedGroups.add(exportedGroup);
+ }
+ }
+ normalizedGroups.addAll(exportedGroupsMap.values());
+ normalizeGroupList(normalizedGroups);
+ return normalizedGroups.isEmpty() ? null : normalizedGroups;
+ }
+
+ public boolean subGroupsChanged(GroupRepresentation exportedGroup, GroupRepresentation baselineGroup) {
+ if (exportedGroup.getSubGroups() == null && baselineGroup.getSubGroups() != null) {
+ return true;
+ }
+ if (exportedGroup.getSubGroups() != null && baselineGroup.getSubGroups() == null) {
+ return true;
+ }
+ if (exportedGroup.getSubGroups() == null && baselineGroup.getSubGroups() == null) {
+ return false;
+ }
+
+ Map exportedSubGroups = exportedGroup.getSubGroups().stream()
+ .collect(Collectors.toMap(GroupRepresentation::getPath, Function.identity()));
+ Map baselineSubGroups = baselineGroup.getSubGroups().stream()
+ .collect(Collectors.toMap(GroupRepresentation::getPath, Function.identity()));
+
+ for (var entry : baselineSubGroups.entrySet()) {
+ var groupPath = entry.getKey();
+ var exportedSubGroup = exportedSubGroups.remove(groupPath);
+
+ if (exportedSubGroup == null) {
+ // There's a subgroup in the baseline that's gone in the export. This counts as a change.
+ return true;
+ }
+ var baselineSubGroup = entry.getValue();
+ if (unOrderedJavers.compare(baselineSubGroup, exportedSubGroup).hasChanges()) {
+ return true;
+ }
+ if (subGroupsChanged(exportedSubGroup, baselineSubGroup)) {
+ return true;
+ }
+ }
+
+ // There are subgroups in the export that are not in the baseline. This is a change.
+ return !exportedSubGroups.isEmpty();
+ }
+
+ public void normalizeGroupList(List groups) {
+ for (var group : groups) {
+ if (group.getAttributes() != null && group.getAttributes().isEmpty()) {
+ group.setAttributes(null);
+ }
+ if (group.getRealmRoles() != null && group.getRealmRoles().isEmpty()) {
+ group.setRealmRoles(null);
+ }
+ if (group.getClientRoles() != null && group.getClientRoles().isEmpty()) {
+ group.setClientRoles(null);
+ }
+ if (group.getSubGroups() != null) {
+ if (group.getSubGroups().isEmpty()) {
+ group.setSubGroups(null);
+ } else {
+ normalizeGroupList(group.getSubGroups());
+ }
+ }
+ group.setId(null);
+ }
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/IdentityProviderNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/IdentityProviderNormalizationService.java
new file mode 100644
index 000000000..a5d87cdcf
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/IdentityProviderNormalizationService.java
@@ -0,0 +1,149 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class IdentityProviderNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(IdentityProviderNormalizationService.class);
+
+ private final Javers unOrderedJavers;
+
+ public IdentityProviderNormalizationService(Javers unOrderedJavers) {
+ this.unOrderedJavers = unOrderedJavers;
+ }
+
+ public List normalizeProviders(List exportedProviders,
+ List baselineProviders) {
+ var exportedOrEmpty = getNonNull(exportedProviders);
+ var baselineOrEmpty = getNonNull(baselineProviders);
+
+ var exportedMap = exportedOrEmpty.stream()
+ .collect(Collectors.toMap(IdentityProviderRepresentation::getAlias, Function.identity()));
+ var baselineMap = baselineOrEmpty.stream()
+ .collect(Collectors.toMap(IdentityProviderRepresentation::getAlias, Function.identity()));
+
+ var normalizedProviders = new ArrayList();
+ for (var entry : baselineMap.entrySet()) {
+ var alias = entry.getKey();
+ var exportedProvider = exportedMap.remove(alias);
+ if (exportedProvider == null) {
+ logger.warn("Default realm identityProvider '{}' was deleted in exported realm. It may be reintroduced during import!", alias);
+ continue;
+ }
+ var baselineProvider = entry.getValue();
+
+ var diff = unOrderedJavers.compare(baselineProvider, exportedProvider);
+ if (diff.hasChanges()) {
+ normalizedProviders.add(exportedProvider);
+ }
+ }
+ normalizedProviders.addAll(exportedMap.values());
+ for (var provider : normalizedProviders) {
+ provider.setInternalId(null);
+ if (provider.getConfig() != null && provider.getConfig().isEmpty()) {
+ provider.setConfig(null);
+ }
+ }
+ return normalizedProviders.isEmpty() ? null : normalizedProviders;
+ }
+
+ public List normalizeMappers(List exportedMappers,
+ List baselineMappers) {
+ var exportedOrEmpty = getNonNull(exportedMappers);
+ var baselineOrEmpty = getNonNull(baselineMappers);
+
+ var exportedMap = exportedOrEmpty.stream()
+ .collect(Collectors.toMap(m -> new MapperKey(m.getName(), m.getIdentityProviderAlias()), Function.identity()));
+ var baselineMap = baselineOrEmpty.stream()
+ .collect(Collectors.toMap(m -> new MapperKey(m.getName(), m.getIdentityProviderAlias()), Function.identity()));
+
+ var normalizedMappers = new ArrayList();
+ for (var entry : baselineMap.entrySet()) {
+ var key = entry.getKey();
+ var exportedMapper = exportedMap.remove(key);
+ if (exportedMapper == null) {
+ logger.warn("Default realm identityProviderMapper '{}' for idp '{}' was deleted in exported realm."
+ + "It may be reintroduced during import!", key.getName(), key.getIdentityProviderAlias());
+ continue;
+ }
+ var baselineMapper = entry.getValue();
+
+ var diff = unOrderedJavers.compare(baselineMapper, exportedMapper);
+ if (diff.hasChanges()) {
+ normalizedMappers.add(exportedMapper);
+ }
+ }
+ normalizedMappers.addAll(exportedMap.values());
+ for (var mapper : normalizedMappers) {
+ mapper.setId(null);
+ }
+ return normalizedMappers.isEmpty() ? null : normalizedMappers;
+ }
+
+ private static class MapperKey {
+ private final String name;
+ private final String identityProviderAlias;
+
+ public MapperKey(String name, String identityProviderAlias) {
+ this.name = name;
+ this.identityProviderAlias = identityProviderAlias;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getIdentityProviderAlias() {
+ return identityProviderAlias;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MapperKey mapperKey = (MapperKey) o;
+ return Objects.equals(name, mapperKey.name) && Objects.equals(identityProviderAlias, mapperKey.identityProviderAlias);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, identityProviderAlias);
+ }
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/ProtocolMapperNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/ProtocolMapperNormalizationService.java
new file mode 100644
index 000000000..1a65f85b6
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/ProtocolMapperNormalizationService.java
@@ -0,0 +1,82 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class ProtocolMapperNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(IdentityProviderNormalizationService.class);
+
+ private final Javers unOrderedJavers;
+
+ public ProtocolMapperNormalizationService(Javers unOrderedJavers) {
+ this.unOrderedJavers = unOrderedJavers;
+ }
+
+ public List normalizeProtocolMappers(List exportedMappers,
+ List baselineMappers) {
+ var exportedOrEmpty = getNonNull(exportedMappers);
+ var baselineOrEmpty = getNonNull(baselineMappers);
+
+ var exportedMap = exportedOrEmpty.stream()
+ .collect(Collectors.toMap(ProtocolMapperRepresentation::getName, Function.identity()));
+ var baselineMap = baselineOrEmpty.stream()
+ .collect(Collectors.toMap(ProtocolMapperRepresentation::getName, Function.identity()));
+ var normalizedMappers = new ArrayList();
+
+ for (var entry : baselineMap.entrySet()) {
+ var name = entry.getKey();
+ var exportedMapper = exportedMap.remove(name);
+ if (exportedMapper == null) {
+ logger.warn("Default realm protocolMapper '{}' was deleted in exported realm. It may be reintroduced during import!", name);
+ continue;
+ }
+
+ var baselineMapper = entry.getValue();
+ if (unOrderedJavers.compare(baselineMapper, exportedMapper).hasChanges()) {
+ normalizedMappers.add(exportedMapper);
+ }
+ }
+ normalizedMappers.addAll(exportedMap.values());
+ for (var mapper : normalizedMappers) {
+ mapper.setId(null);
+ if (mapper.getConfig() != null && mapper.getConfig().isEmpty()) {
+ mapper.setConfig(null);
+ }
+ }
+ return normalizedMappers.isEmpty() ? null : normalizedMappers;
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/RealmNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/RealmNormalizationService.java
new file mode 100644
index 000000000..cb9e1b16b
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/RealmNormalizationService.java
@@ -0,0 +1,211 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import de.adorsys.keycloak.config.properties.NormalizationKeycloakConfigProperties;
+import de.adorsys.keycloak.config.provider.BaselineProvider;
+import de.adorsys.keycloak.config.util.JaversUtil;
+import org.javers.core.Javers;
+import org.javers.core.diff.changetype.PropertyChange;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class RealmNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(RealmNormalizationService.class);
+
+ private final NormalizationKeycloakConfigProperties keycloakConfigProperties;
+ private final Javers javers;
+ private final BaselineProvider baselineProvider;
+ private final ClientNormalizationService clientNormalizationService;
+ private final ScopeMappingNormalizationService scopeMappingNormalizationService;
+ private final ProtocolMapperNormalizationService protocolMapperNormalizationService;
+ private final ClientScopeNormalizationService clientScopeNormalizationService;
+ private final RoleNormalizationService roleNormalizationService;
+ private final AttributeNormalizationService attributeNormalizationService;
+ private final GroupNormalizationService groupNormalizationService;
+ private final AuthFlowNormalizationService authFlowNormalizationService;
+ private final IdentityProviderNormalizationService identityProviderNormalizationService;
+ private final RequiredActionNormalizationService requiredActionNormalizationService;
+ private final UserFederationNormalizationService userFederationNormalizationService;
+ private final ClientPolicyNormalizationService clientPolicyNormalizationService;
+ private final JaversUtil javersUtil;
+
+ @Autowired
+ public RealmNormalizationService(NormalizationKeycloakConfigProperties keycloakConfigProperties,
+ Javers javers,
+ BaselineProvider baselineProvider,
+ ClientNormalizationService clientNormalizationService,
+ ScopeMappingNormalizationService scopeMappingNormalizationService,
+ ProtocolMapperNormalizationService protocolMapperNormalizationService,
+ ClientScopeNormalizationService clientScopeNormalizationService,
+ RoleNormalizationService roleNormalizationService,
+ AttributeNormalizationService attributeNormalizationService,
+ GroupNormalizationService groupNormalizationService,
+ AuthFlowNormalizationService authFlowNormalizationService,
+ IdentityProviderNormalizationService identityProviderNormalizationService,
+ RequiredActionNormalizationService requiredActionNormalizationService,
+ UserFederationNormalizationService userFederationNormalizationService,
+ ClientPolicyNormalizationService clientPolicyNormalizationService,
+ JaversUtil javersUtil) {
+ this.keycloakConfigProperties = keycloakConfigProperties;
+ this.javers = javers;
+ this.baselineProvider = baselineProvider;
+ this.clientNormalizationService = clientNormalizationService;
+ this.scopeMappingNormalizationService = scopeMappingNormalizationService;
+ this.protocolMapperNormalizationService = protocolMapperNormalizationService;
+ this.clientScopeNormalizationService = clientScopeNormalizationService;
+ this.roleNormalizationService = roleNormalizationService;
+ this.attributeNormalizationService = attributeNormalizationService;
+ this.groupNormalizationService = groupNormalizationService;
+ this.authFlowNormalizationService = authFlowNormalizationService;
+ this.identityProviderNormalizationService = identityProviderNormalizationService;
+ this.requiredActionNormalizationService = requiredActionNormalizationService;
+ this.userFederationNormalizationService = userFederationNormalizationService;
+ this.clientPolicyNormalizationService = clientPolicyNormalizationService;
+ this.javersUtil = javersUtil;
+
+ // TODO allow extra "default" values to be ignored?
+
+ // TODO Ignore clients by regex
+ }
+
+ public RealmRepresentation normalizeRealm(RealmRepresentation exportedRealm) {
+ var keycloakConfigVersion = keycloakConfigProperties.getVersion();
+ var exportVersion = exportedRealm.getKeycloakVersion();
+ if (!exportVersion.equals(keycloakConfigVersion)) {
+ logger.warn("Keycloak-Config-CLI keycloak version {} and export keycloak version {} are not equal."
+ + " This may cause problems if the API changed."
+ + " Please compile keycloak-config-cli with a matching keycloak version!",
+ keycloakConfigVersion, exportVersion);
+ }
+ var exportedRealmRealm = exportedRealm.getRealm();
+ logger.info("Exporting realm {}", exportedRealmRealm);
+ var baselineRealm = baselineProvider.getRealm(exportVersion, exportedRealmRealm);
+
+ /*
+ * Trick javers into thinking this is the "same" object, by setting the ID on the reference realm
+ * to the ID of the current realm. That way we only get actual changes, not a full list of changes
+ * including the "object removed" and "object added" changes
+ */
+ baselineRealm.setRealm(exportedRealm.getRealm());
+ var minimizedRealm = new RealmRepresentation();
+
+ handleBaseRealm(exportedRealm, baselineRealm, minimizedRealm);
+
+ var clients = clientNormalizationService.normalizeClients(exportedRealm, baselineRealm);
+ if (!clients.isEmpty()) {
+ minimizedRealm.setClients(clients);
+ }
+
+ // No setter for some reason...
+ var minimizedScopeMappings = scopeMappingNormalizationService.normalizeScopeMappings(exportedRealm, baselineRealm);
+ if (!minimizedScopeMappings.isEmpty()) {
+ var scopeMappings = minimizedRealm.getScopeMappings();
+ if (scopeMappings == null) {
+ minimizedRealm.clientScopeMapping("dummy");
+ scopeMappings = minimizedRealm.getScopeMappings();
+ scopeMappings.clear();
+ }
+ scopeMappings.addAll(minimizedScopeMappings);
+ }
+
+ var clientScopeMappings = scopeMappingNormalizationService.normalizeClientScopeMappings(exportedRealm, baselineRealm);
+ if (!clientScopeMappings.isEmpty()) {
+ minimizedRealm.setClientScopeMappings(clientScopeMappings);
+ }
+
+ minimizedRealm.setAttributes(attributeNormalizationService.normalizeStringAttributes(exportedRealm.getAttributes(),
+ baselineRealm.getAttributes()));
+
+ minimizedRealm.setProtocolMappers(protocolMapperNormalizationService.normalizeProtocolMappers(exportedRealm.getProtocolMappers(),
+ baselineRealm.getProtocolMappers()));
+
+ minimizedRealm.setClientScopes(clientScopeNormalizationService.normalizeClientScopes(exportedRealm.getClientScopes(),
+ baselineRealm.getClientScopes()));
+
+ minimizedRealm.setRoles(roleNormalizationService.normalizeRoles(exportedRealm.getRoles(), baselineRealm.getRoles()));
+
+ minimizedRealm.setGroups(groupNormalizationService.normalizeGroups(exportedRealm.getGroups(), baselineRealm.getGroups()));
+
+ var authFlows = authFlowNormalizationService.normalizeAuthFlows(exportedRealm.getAuthenticationFlows(),
+ baselineRealm.getAuthenticationFlows());
+ minimizedRealm.setAuthenticationFlows(authFlows);
+ minimizedRealm.setAuthenticatorConfig(authFlowNormalizationService.normalizeAuthConfig(exportedRealm.getAuthenticatorConfig(), authFlows));
+
+ minimizedRealm.setIdentityProviders(identityProviderNormalizationService.normalizeProviders(exportedRealm.getIdentityProviders(),
+ baselineRealm.getIdentityProviders()));
+ minimizedRealm.setIdentityProviderMappers(identityProviderNormalizationService.normalizeMappers(exportedRealm.getIdentityProviderMappers(),
+ baselineRealm.getIdentityProviderMappers()));
+
+ minimizedRealm.setRequiredActions(requiredActionNormalizationService.normalizeRequiredActions(exportedRealm.getRequiredActions(),
+ baselineRealm.getRequiredActions()));
+ minimizedRealm.setUserFederationProviders(userFederationNormalizationService.normalizeProviders(exportedRealm.getUserFederationProviders(),
+ baselineRealm.getUserFederationProviders()));
+ minimizedRealm.setUserFederationMappers(userFederationNormalizationService.normalizeMappers(exportedRealm.getUserFederationMappers(),
+ baselineRealm.getUserFederationMappers()));
+
+ minimizedRealm.setParsedClientPolicies(clientPolicyNormalizationService.normalizePolicies(exportedRealm.getParsedClientPolicies(),
+ baselineRealm.getParsedClientPolicies()));
+ minimizedRealm.setParsedClientProfiles(clientPolicyNormalizationService.normalizeProfiles(exportedRealm.getParsedClientProfiles(),
+ baselineRealm.getParsedClientProfiles()));
+ return minimizedRealm;
+ }
+
+ private void handleBaseRealm(RealmRepresentation exportedRealm, RealmRepresentation baselineRealm, RealmRepresentation minimizedRealm) {
+ var diff = javers.compare(baselineRealm, exportedRealm);
+ for (var change : diff.getChangesByType(PropertyChange.class)) {
+ javersUtil.applyChange(minimizedRealm, change);
+ }
+
+ // Now that Javers is done, clean up a bit afterwards. We always need to set the realm and enabled fields
+ minimizedRealm.setRealm(exportedRealm.getRealm());
+ minimizedRealm.setEnabled(exportedRealm.isEnabled());
+
+ // If the realm ID diverges from the name, include it in the dump, otherwise remove it
+ if (Objects.equals(exportedRealm.getRealm(), exportedRealm.getId())) {
+ minimizedRealm.setId(null);
+ } else {
+ minimizedRealm.setId(exportedRealm.getId());
+ }
+ }
+
+
+ public static Map getNonNull(Map in) {
+ return in == null ? new HashMap<>() : in;
+ }
+
+ public static List getNonNull(List in) {
+ return in == null ? new ArrayList<>() : in;
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/RequiredActionNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/RequiredActionNormalizationService.java
new file mode 100644
index 000000000..361357d0d
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/RequiredActionNormalizationService.java
@@ -0,0 +1,77 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class RequiredActionNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(RequiredActionNormalizationService.class);
+
+ private final Javers javers;
+
+ public RequiredActionNormalizationService(Javers javers) {
+ this.javers = javers;
+ }
+
+ public List normalizeRequiredActions(List exportedActions,
+ List baselineActions) {
+ var exportedOrEmpty = getNonNull(exportedActions);
+ var baselineOrEmpty = getNonNull(baselineActions);
+
+ var exportedMap = exportedOrEmpty.stream()
+ .collect(Collectors.toMap(RequiredActionProviderRepresentation::getAlias, Function.identity()));
+ var baselineMap = baselineOrEmpty.stream()
+ .collect(Collectors.toMap(RequiredActionProviderRepresentation::getAlias, Function.identity()));
+
+ var normalizedActions = new ArrayList();
+ for (var entry : baselineMap.entrySet()) {
+ var alias = entry.getKey();
+ var exportedAction = exportedMap.remove(alias);
+ if (exportedAction == null) {
+ logger.warn("Default realm requiredAction '{}' was deleted in exported realm. It may be reintroduced during import", alias);
+ continue;
+ }
+ var baselineAction = entry.getValue();
+
+ var diff = javers.compare(baselineAction, exportedAction);
+ if (diff.hasChanges()) {
+ normalizedActions.add(exportedAction);
+ }
+ }
+ normalizedActions.addAll(exportedMap.values());
+ return normalizedActions.isEmpty() ? null : normalizedActions;
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/RoleNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/RoleNormalizationService.java
new file mode 100644
index 000000000..a4209b8a3
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/RoleNormalizationService.java
@@ -0,0 +1,161 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.RolesRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class RoleNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(RoleNormalizationService.class);
+
+ private final Javers unOrderedJavers;
+ private final AttributeNormalizationService attributeNormalizationService;
+
+ @Autowired
+ public RoleNormalizationService(Javers unOrderedJavers, AttributeNormalizationService attributeNormalizationService) {
+ this.unOrderedJavers = unOrderedJavers;
+ this.attributeNormalizationService = attributeNormalizationService;
+ }
+
+ public RolesRepresentation normalizeRoles(RolesRepresentation exportedRoles, RolesRepresentation baselineRoles) {
+ var exportedOrEmpty = exportedRoles == null ? new RolesRepresentation() : exportedRoles;
+ var baselineOrEmpty = baselineRoles == null ? new RolesRepresentation() : baselineRoles;
+ var clientRoles = normalizeClientRoles(exportedOrEmpty.getClient(), baselineOrEmpty.getClient());
+ var realmRoles = normalizeRealmRoles(exportedOrEmpty.getRealm(), baselineOrEmpty.getRealm());
+ var normalizedRoles = new RolesRepresentation();
+ if (!clientRoles.isEmpty()) {
+ normalizedRoles.setClient(clientRoles);
+ }
+ if (!realmRoles.isEmpty()) {
+ normalizedRoles.setRealm(realmRoles);
+ }
+
+ // avoid generating an empty roles element
+ if (normalizedRoles.getRealm() == null || (normalizedRoles.getRealm().isEmpty() && normalizedRoles.getClient().isEmpty())) {
+ return null;
+ }
+
+ return normalizedRoles;
+ }
+
+ public List normalizeRealmRoles(List exportedRoles, List baselineRoles) {
+ return normalizeRoleList(exportedRoles, baselineRoles, null);
+ }
+
+ public Map> normalizeClientRoles(Map> exportedRoles,
+ Map> baselineRoles) {
+ var exportedOrEmpty = getNonNull(exportedRoles);
+ var baselineOrEmpty = getNonNull(baselineRoles);
+
+ var normalizedRoles = new HashMap>();
+ for (var entry : baselineOrEmpty.entrySet()) {
+ var clientId = entry.getKey();
+ var baselineClientRoles = entry.getValue();
+ var exportedClientRoles = exportedOrEmpty.remove(clientId);
+ exportedClientRoles = getNonNull(exportedClientRoles);
+
+ var normalizedClientRoles = normalizeRoleList(exportedClientRoles, baselineClientRoles, clientId);
+ if (!normalizedClientRoles.isEmpty()) {
+ normalizedRoles.put(clientId, normalizedClientRoles);
+ }
+ }
+
+ for (var entry : exportedOrEmpty.entrySet()) {
+ var clientId = entry.getKey();
+ var roles = entry.getValue();
+
+ if (!roles.isEmpty()) {
+ normalizedRoles.put(clientId, normalizeList(roles));
+ }
+ }
+ return normalizedRoles;
+ }
+
+ public List normalizeRoleList(List exportedRoles,
+ List baselineRoles, String clientId) {
+ var exportedOrEmpty = getNonNull(exportedRoles);
+ var baselineOrEmpty = getNonNull(baselineRoles);
+
+ var exportedMap = exportedOrEmpty.stream()
+ .collect(Collectors.toMap(RoleRepresentation::getName, Function.identity()));
+ var baselineMap = baselineOrEmpty.stream()
+ .collect(Collectors.toMap(RoleRepresentation::getName, Function.identity()));
+ var normalizedRoles = new ArrayList();
+ for (var entry : baselineMap.entrySet()) {
+ var roleName = entry.getKey();
+ var exportedRole = exportedMap.remove(roleName);
+ if (exportedRole == null) {
+ if (clientId == null) {
+ logger.warn("Default realm role '{}' was deleted in exported realm. It may be reintroduced during import!", roleName);
+ } else {
+ logger.warn("Default realm client-role '{}' for client '{}' was deleted in the exported realm. "
+ + "It may be reintroduced during import!", roleName, clientId);
+ }
+ continue;
+ }
+
+ var baselineRole = entry.getValue();
+
+ var diff = unOrderedJavers.compare(baselineRole, exportedRole);
+
+ if (diff.hasChanges()
+ || compositesChanged(exportedRole.getComposites(), baselineRole.getComposites())
+ || attributeNormalizationService.listAttributesChanged(exportedRole.getAttributes(), baselineRole.getAttributes())) {
+ normalizedRoles.add(exportedRole);
+ }
+ }
+ normalizedRoles.addAll(exportedMap.values());
+ return normalizeList(normalizedRoles);
+ }
+
+ public List normalizeList(List roles) {
+ for (var role : roles) {
+ role.setId(null);
+ if (role.getAttributes() != null && role.getAttributes().isEmpty()) {
+ role.setAttributes(null);
+ }
+ }
+ return roles;
+ }
+
+ public boolean compositesChanged(RoleRepresentation.Composites exportedComposites, RoleRepresentation.Composites baselineComposites) {
+ return unOrderedJavers.compare(baselineComposites, exportedComposites)
+ .hasChanges();
+ }
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/ScopeMappingNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/ScopeMappingNormalizationService.java
new file mode 100644
index 000000000..f713a2351
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/ScopeMappingNormalizationService.java
@@ -0,0 +1,117 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.ScopeMappingRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class ScopeMappingNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(ScopeMappingNormalizationService.class);
+
+ private final Javers javers;
+
+ public ScopeMappingNormalizationService(Javers javers) {
+ this.javers = javers;
+ }
+
+ public List normalizeScopeMappings(RealmRepresentation exportedRealm, RealmRepresentation baselineRealm) {
+ /*
+ * TODO: are the mappings in scopeMappings always clientScope/role? If not, this breaks
+ */
+ // First handle the "default" scopeMappings present in the
+ var exportedMappingsMap = new HashMap();
+ for (var exportedMapping : exportedRealm.getScopeMappings()) {
+ exportedMappingsMap.put(exportedMapping.getClientScope(), exportedMapping);
+ }
+
+ var baselineMappingsMap = new HashMap();
+
+ var mappings = new ArrayList();
+ for (var baselineRealmMapping : baselineRealm.getScopeMappings()) {
+ var clientScope = baselineRealmMapping.getClientScope();
+ baselineMappingsMap.put(clientScope, baselineRealmMapping);
+ var exportedMapping = exportedMappingsMap.get(clientScope);
+ if (exportedMapping == null) {
+ logger.warn("Default realm scopeMapping '{}' was deleted in exported realm. It may be reintroduced during import!", clientScope);
+ continue;
+ }
+ // If the exported scopeMapping is different from the one that is present in the baseline realm, export it in the yml
+ if (scopeMappingChanged(exportedMapping, baselineRealmMapping)) {
+ mappings.add(exportedMapping);
+ }
+ }
+
+ for (Map.Entry e : exportedMappingsMap.entrySet()) {
+ var clientScope = e.getKey();
+ if (!baselineMappingsMap.containsKey(clientScope)) {
+ mappings.add(e.getValue());
+ }
+ }
+ return mappings;
+ }
+
+ public Map> normalizeClientScopeMappings(RealmRepresentation exportedRealm,
+ RealmRepresentation baselineRealm) {
+ var baselineOrEmpty = getNonNull(baselineRealm.getClientScopeMappings());
+ var exportedOrEmpty = getNonNull(exportedRealm.getClientScopeMappings());
+
+ var mappings = new HashMap>();
+ for (var e : baselineOrEmpty.entrySet()) {
+ var key = e.getKey();
+ if (!exportedOrEmpty.containsKey(key)) {
+ logger.warn("Default realm clientScopeMapping '{}' was deleted in exported realm. It may be reintroduced during import!", key);
+ continue;
+ }
+ var scopeMappings = exportedOrEmpty.get(key);
+ if (javers.compareCollections(e.getValue(), scopeMappings, ScopeMappingRepresentation.class).hasChanges()) {
+ mappings.put(key, scopeMappings);
+ }
+ }
+
+ for (var e : exportedOrEmpty.entrySet()) {
+ var key = e.getKey();
+ if (!baselineOrEmpty.containsKey(key)) {
+ mappings.put(key, e.getValue());
+ }
+ }
+ return mappings;
+ }
+
+ public boolean scopeMappingChanged(ScopeMappingRepresentation exportedMapping, ScopeMappingRepresentation baselineRealmMapping) {
+ return javers.compare(baselineRealmMapping, exportedMapping).hasChanges();
+ }
+
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/normalize/UserFederationNormalizationService.java b/src/main/java/de/adorsys/keycloak/config/service/normalize/UserFederationNormalizationService.java
new file mode 100644
index 000000000..2821b7b39
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/service/normalize/UserFederationNormalizationService.java
@@ -0,0 +1,154 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2023 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.service.normalize;
+
+import org.javers.core.Javers;
+import org.keycloak.representations.idm.UserFederationMapperRepresentation;
+import org.keycloak.representations.idm.UserFederationProviderRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static de.adorsys.keycloak.config.service.normalize.RealmNormalizationService.getNonNull;
+
+@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class UserFederationNormalizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(UserFederationNormalizationService.class);
+
+ private final Javers unOrderedJavers;
+
+ @Autowired
+ public UserFederationNormalizationService(Javers unOrderedJavers) {
+ this.unOrderedJavers = unOrderedJavers;
+ }
+
+ public List normalizeProviders(List exportedProviders,
+ List baselineProviders) {
+ var exportedOrEmpty = getNonNull(exportedProviders);
+ var baselineOrEmpty = getNonNull(baselineProviders);
+
+ var exportedMap = exportedOrEmpty.stream()
+ .collect(Collectors.toMap(UserFederationProviderRepresentation::getDisplayName, Function.identity()));
+ var baselineMap = baselineOrEmpty.stream()
+ .collect(Collectors.toMap(UserFederationProviderRepresentation::getDisplayName, Function.identity()));
+
+ var normalizedProviders = new ArrayList();
+ for (var entry : baselineMap.entrySet()) {
+ var displayName = entry.getKey();
+ var exportedProvider = exportedMap.remove(displayName);
+
+ if (exportedProvider == null) {
+ logger.warn("Default realm UserFederationProvider '{}' was deleted in exported realm. "
+ + "It may be reintroduced during import!", displayName);
+ continue;
+ }
+
+ var baselineProvider = entry.getValue();
+ if (unOrderedJavers.compare(baselineProvider, exportedProvider).hasChanges()) {
+ normalizedProviders.add(exportedProvider);
+ }
+ }
+ normalizedProviders.addAll(exportedMap.values());
+ for (var provider : normalizedProviders) {
+ provider.setId(null);
+ if (provider.getConfig() != null && provider.getConfig().isEmpty()) {
+ provider.setConfig(null);
+ }
+ }
+ return normalizedProviders.isEmpty() ? null : normalizedProviders;
+ }
+
+ public List normalizeMappers(List exportedMappers,
+ List baselineMappers) {
+ var exportedOrEmpty = getNonNull(exportedMappers);
+ var baselineOrEmpty = getNonNull(baselineMappers);
+
+ var exportedMap = exportedOrEmpty.stream()
+ .collect(Collectors.toMap(m -> new MapperKey(m.getName(), m.getFederationProviderDisplayName()), Function.identity()));
+ var baselineMap = baselineOrEmpty.stream()
+ .collect(Collectors.toMap(m -> new MapperKey(m.getName(), m.getFederationProviderDisplayName()), Function.identity()));
+
+ var normalizedMappers = new ArrayList();
+ for (var entry : baselineMap.entrySet()) {
+ var key = entry.getKey();
+ var exportedMapper = exportedMap.remove(key);
+ if (exportedMapper == null) {
+ logger.warn("Default realm UserFederationMapper '{}' for federation '{}' was deleted in exported realm. "
+ + "It may be reintroduced during import!", key.getName(), key.getFederationDisplayName());
+ }
+
+ var baselineMapper = entry.getValue();
+ if (unOrderedJavers.compare(baselineMapper, exportedMapper).hasChanges()) {
+ normalizedMappers.add(exportedMapper);
+ }
+ }
+ normalizedMappers.addAll(exportedMap.values());
+ for (var mapper : normalizedMappers) {
+ mapper.setId(null);
+ if (mapper.getConfig() != null && mapper.getConfig().isEmpty()) {
+ mapper.setConfig(null);
+ }
+ }
+ return normalizedMappers.isEmpty() ? null : normalizedMappers;
+ }
+
+ private static class MapperKey {
+ private final String name;
+ private final String federationDisplayName;
+
+ public MapperKey(String name, String federationDisplayName) {
+ this.name = name;
+ this.federationDisplayName = federationDisplayName;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getFederationDisplayName() {
+ return federationDisplayName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ UserFederationNormalizationService.MapperKey mapperKey = (UserFederationNormalizationService.MapperKey) o;
+ return Objects.equals(name, mapperKey.name) && Objects.equals(federationDisplayName, mapperKey.federationDisplayName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, federationDisplayName);
+ }
+ }
+
+}
diff --git a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/ClientCompositeImport.java b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/ClientCompositeImport.java
index 742a51ba8..488b8b9a4 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/ClientCompositeImport.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/ClientCompositeImport.java
@@ -26,12 +26,14 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Service("clientRoleClientCompositeImport")
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientCompositeImport {
private static final Logger logger = LoggerFactory.getLogger(ClientCompositeImport.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/ClientRoleCompositeImportService.java b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/ClientRoleCompositeImportService.java
index 2130abc0c..05b56fa43 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/ClientRoleCompositeImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/ClientRoleCompositeImportService.java
@@ -22,6 +22,7 @@
import org.keycloak.representations.idm.RoleRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -32,6 +33,7 @@
* Implements the update mechanism for role composites of client-level roles
*/
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientRoleCompositeImportService {
private final RealmCompositeImport realmCompositeImport;
diff --git a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/RealmCompositeImport.java b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/RealmCompositeImport.java
index 1fe734179..126fd06eb 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/RealmCompositeImport.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/client/RealmCompositeImport.java
@@ -25,6 +25,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.Objects;
@@ -32,6 +33,7 @@
import java.util.stream.Collectors;
@Service("clientRoleRealmCompositeImport")
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RealmCompositeImport {
private static final Logger logger = LoggerFactory.getLogger(RealmCompositeImport.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/ClientCompositeImport.java b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/ClientCompositeImport.java
index ccfdf78c2..b469ec973 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/ClientCompositeImport.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/ClientCompositeImport.java
@@ -25,12 +25,14 @@
import org.keycloak.representations.idm.RoleRepresentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Service("realmRoleClientCompositeImport")
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class ClientCompositeImport {
private static final Logger logger = LoggerFactory.getLogger(ClientCompositeImport.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/RealmCompositeImport.java b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/RealmCompositeImport.java
index e7eb4f7ac..1cb9aa31d 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/RealmCompositeImport.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/RealmCompositeImport.java
@@ -25,6 +25,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.Objects;
@@ -32,6 +33,7 @@
import java.util.stream.Collectors;
@Service("realmRoleRealmCompositeImport")
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RealmCompositeImport {
private static final Logger logger = LoggerFactory.getLogger(RealmCompositeImport.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/RealmRoleCompositeImportService.java b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/RealmRoleCompositeImportService.java
index 5292af18c..b3d484e86 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/RealmRoleCompositeImportService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/rolecomposites/realm/RealmRoleCompositeImportService.java
@@ -22,6 +22,7 @@
import org.keycloak.representations.idm.RoleRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -31,6 +32,7 @@
* Implements the update mechanism for role composites of realm-level roles
*/
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class RealmRoleCompositeImportService {
private final RealmCompositeImport realmCompositeImport;
diff --git a/src/main/java/de/adorsys/keycloak/config/service/state/StateService.java b/src/main/java/de/adorsys/keycloak/config/service/state/StateService.java
index 7cecd6d78..8913c53a7 100644
--- a/src/main/java/de/adorsys/keycloak/config/service/state/StateService.java
+++ b/src/main/java/de/adorsys/keycloak/config/service/state/StateService.java
@@ -29,6 +29,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -36,6 +37,7 @@
import java.util.Map;
@Service
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class StateService {
private static final Logger logger = LoggerFactory.getLogger(StateService.class);
diff --git a/src/main/java/de/adorsys/keycloak/config/util/JaversUtil.java b/src/main/java/de/adorsys/keycloak/config/util/JaversUtil.java
new file mode 100644
index 000000000..6ec32867c
--- /dev/null
+++ b/src/main/java/de/adorsys/keycloak/config/util/JaversUtil.java
@@ -0,0 +1,42 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2022 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.util;
+
+import de.adorsys.keycloak.config.exception.NormalizationException;
+import org.javers.core.diff.changetype.PropertyChange;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class JaversUtil {
+
+ public void applyChange(Object object, PropertyChange> change) {
+ try {
+ var field = object.getClass().getDeclaredField(change.getPropertyName());
+ field.setAccessible(true);
+ field.set(object, change.getRight());
+ } catch (NoSuchFieldException | IllegalAccessException ex) {
+ throw new NormalizationException(String.format("Failed to set property %s on object of type %s",
+ change.getPropertyName(), object.getClass().getName()), ex);
+ }
+ }
+}
diff --git a/src/main/resources/application-normalize-dev.properties b/src/main/resources/application-normalize-dev.properties
new file mode 100644
index 000000000..ada43bd0e
--- /dev/null
+++ b/src/main/resources/application-normalize-dev.properties
@@ -0,0 +1,6 @@
+spring.output.ansi.enabled=ALWAYS
+spring.config.import=classpath:application-debug.properties
+
+run.operation=NORMALIZE
+normalization.files.input-locations=./exports/in/*.json
+normalization.files.output-directory=./exports/out
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 25641213d..cae13948a 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -6,6 +6,8 @@ spring.main.lazy-initialization=true
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration
keycloak.version=@keycloak.version@
+normalize.version=@keycloak.version@
+
keycloak.login-realm=master
keycloak.user=admin
keycloak.client-secret=
diff --git a/src/main/resources/baseline/19.0.3/client/client.json b/src/main/resources/baseline/19.0.3/client/client.json
new file mode 100644
index 000000000..858b1115b
--- /dev/null
+++ b/src/main/resources/baseline/19.0.3/client/client.json
@@ -0,0 +1,45 @@
+{
+ "id": "caa6606a-6056-475c-af05-8b0365bb8164",
+ "clientId": "reference-client",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "q0t682YLCCk2qd5dntjtcniGozLXIZ7h",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "client.secret.creation.time": "1667920370"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": true,
+ "nodeReRegistrationTimeout": -1,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ],
+ "access": {
+ "view": true,
+ "configure": true,
+ "manage": true
+ }
+}
diff --git a/src/main/resources/baseline/19.0.3/realm/realm.json b/src/main/resources/baseline/19.0.3/realm/realm.json
new file mode 100644
index 000000000..bf14005cb
--- /dev/null
+++ b/src/main/resources/baseline/19.0.3/realm/realm.json
@@ -0,0 +1,2176 @@
+{
+ "id": "REALM_NAME_PLACEHOLDER",
+ "realm": "REALM_NAME_PLACEHOLDER",
+ "notBefore": 0,
+ "defaultSignatureAlgorithm": "RS256",
+ "revokeRefreshToken": false,
+ "refreshTokenMaxReuse": 0,
+ "accessTokenLifespan": 300,
+ "accessTokenLifespanForImplicitFlow": 900,
+ "ssoSessionIdleTimeout": 1800,
+ "ssoSessionMaxLifespan": 36000,
+ "ssoSessionIdleTimeoutRememberMe": 0,
+ "ssoSessionMaxLifespanRememberMe": 0,
+ "offlineSessionIdleTimeout": 2592000,
+ "offlineSessionMaxLifespanEnabled": false,
+ "offlineSessionMaxLifespan": 5184000,
+ "clientSessionIdleTimeout": 0,
+ "clientSessionMaxLifespan": 0,
+ "clientOfflineSessionIdleTimeout": 0,
+ "clientOfflineSessionMaxLifespan": 0,
+ "accessCodeLifespan": 60,
+ "accessCodeLifespanUserAction": 300,
+ "accessCodeLifespanLogin": 1800,
+ "actionTokenGeneratedByAdminLifespan": 43200,
+ "actionTokenGeneratedByUserLifespan": 300,
+ "oauth2DeviceCodeLifespan": 600,
+ "oauth2DevicePollingInterval": 5,
+ "enabled": true,
+ "sslRequired": "external",
+ "registrationAllowed": false,
+ "registrationEmailAsUsername": false,
+ "rememberMe": false,
+ "verifyEmail": false,
+ "loginWithEmailAllowed": true,
+ "duplicateEmailsAllowed": false,
+ "resetPasswordAllowed": false,
+ "editUsernameAllowed": false,
+ "bruteForceProtected": false,
+ "permanentLockout": false,
+ "maxFailureWaitSeconds": 900,
+ "minimumQuickLoginWaitSeconds": 60,
+ "waitIncrementSeconds": 60,
+ "quickLoginCheckMilliSeconds": 1000,
+ "maxDeltaTimeSeconds": 43200,
+ "failureFactor": 30,
+ "roles": {
+ "realm": [
+ {
+ "id": "0825e37b-b5bb-413d-9c1c-23457f17cb66",
+ "name": "default-roles-REALM_NAME_PLACEHOLDER",
+ "description": "${role_default-roles}",
+ "composite": true,
+ "composites": {
+ "realm": [
+ "offline_access",
+ "uma_authorization"
+ ],
+ "client": {
+ "account": [
+ "manage-account",
+ "view-profile"
+ ]
+ }
+ },
+ "clientRole": false,
+ "containerId": "REALM_NAME_PLACEHOLDER",
+ "attributes": {}
+ },
+ {
+ "id": "08b30ae4-52ba-45a9-b723-07e6ac57ae2f",
+ "name": "offline_access",
+ "description": "${role_offline-access}",
+ "composite": false,
+ "clientRole": false,
+ "containerId": "REALM_NAME_PLACEHOLDER",
+ "attributes": {}
+ },
+ {
+ "id": "372ddfc2-cd6e-4ca3-a30f-d39cb92ac12d",
+ "name": "uma_authorization",
+ "description": "${role_uma_authorization}",
+ "composite": false,
+ "clientRole": false,
+ "containerId": "REALM_NAME_PLACEHOLDER",
+ "attributes": {}
+ }
+ ],
+ "client": {
+ "realm-management": [
+ {
+ "id": "caf6ae68-6a16-4dfa-9a71-1149ceb8f79c",
+ "name": "manage-identity-providers",
+ "description": "${role_manage-identity-providers}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "913aeddb-8be9-4060-86c7-30cf0fa892ee",
+ "name": "manage-users",
+ "description": "${role_manage-users}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "15ee649c-ef5f-4fe8-a6c1-67a9db14b0c5",
+ "name": "view-clients",
+ "description": "${role_view-clients}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "query-clients"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "5d56f881-d3ff-49ad-929c-214afd641f8f",
+ "name": "query-clients",
+ "description": "${role_query-clients}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "0ba58546-8487-4508-b81f-0735432accf2",
+ "name": "view-events",
+ "description": "${role_view-events}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "f6f1b3c0-5d29-41b4-b2ec-cfab60e28a3b",
+ "name": "query-users",
+ "description": "${role_query-users}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "2c6ddc11-206e-4e82-b894-9fca7cc85866",
+ "name": "view-realm",
+ "description": "${role_view-realm}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "f9917916-7aca-413b-b7bc-452d3fca7a48",
+ "name": "manage-events",
+ "description": "${role_manage-events}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "ad1d551b-3f03-445d-8ac0-51b1196413f0",
+ "name": "view-users",
+ "description": "${role_view-users}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "query-groups",
+ "query-users"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "f645cca6-9d25-40f0-8ce9-d988a04d9bec",
+ "name": "create-client",
+ "description": "${role_create-client}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "ce56402a-8925-4750-9269-6b035cfa334f",
+ "name": "impersonation",
+ "description": "${role_impersonation}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "1e70f63f-0883-4452-bb1b-f179bf3c8c30",
+ "name": "manage-authorization",
+ "description": "${role_manage-authorization}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "5cef1f90-8af8-4445-b6a3-05d6eb60c46c",
+ "name": "manage-realm",
+ "description": "${role_manage-realm}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "e87e4aa8-8c15-44ba-9622-eec4eeae1997",
+ "name": "query-groups",
+ "description": "${role_query-groups}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "baa31234-e4ed-4821-a696-6ccd686b5e1f",
+ "name": "view-identity-providers",
+ "description": "${role_view-identity-providers}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "0d7127a0-cd7b-478c-9156-629fc321bca4",
+ "name": "query-realms",
+ "description": "${role_query-realms}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "99d07b51-633c-4d25-9dc1-f779a219c246",
+ "name": "realm-admin",
+ "description": "${role_realm-admin}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "manage-users",
+ "manage-identity-providers",
+ "view-clients",
+ "query-clients",
+ "view-events",
+ "query-users",
+ "view-realm",
+ "manage-events",
+ "view-users",
+ "create-client",
+ "manage-authorization",
+ "impersonation",
+ "manage-realm",
+ "view-identity-providers",
+ "query-groups",
+ "query-realms",
+ "manage-clients",
+ "view-authorization"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "118c289f-0b71-4edf-ac2a-7016cc0c674d",
+ "name": "manage-clients",
+ "description": "${role_manage-clients}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ },
+ {
+ "id": "30f43104-6914-4e4f-9f6d-219daf2f7991",
+ "name": "view-authorization",
+ "description": "${role_view-authorization}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "attributes": {}
+ }
+ ],
+ "security-admin-console": [],
+ "admin-cli": [],
+ "account-console": [],
+ "broker": [
+ {
+ "id": "6045a69a-aec3-4a11-b4c3-3cae53f7a914",
+ "name": "read-token",
+ "description": "${role_read-token}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6eed48a3-64bd-48ed-ac7c-607f8e724258",
+ "attributes": {}
+ }
+ ],
+ "account": [
+ {
+ "id": "4e27eb76-06ea-4547-ab5d-de8f9c745597",
+ "name": "manage-consent",
+ "description": "${role_manage-consent}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "account": [
+ "view-consent"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "6c7757f2-9ed7-4609-8e41-f4316ca8d31e",
+ "attributes": {}
+ },
+ {
+ "id": "60ae83a6-6ed1-4b4f-81cc-701b9a95ceb9",
+ "name": "delete-account",
+ "description": "${role_delete-account}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6c7757f2-9ed7-4609-8e41-f4316ca8d31e",
+ "attributes": {}
+ },
+ {
+ "id": "f5f244ba-53de-45d7-9774-d4c915cd4ccb",
+ "name": "manage-account",
+ "description": "${role_manage-account}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "account": [
+ "manage-account-links"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "6c7757f2-9ed7-4609-8e41-f4316ca8d31e",
+ "attributes": {}
+ },
+ {
+ "id": "2abb2ef2-3e4c-43d5-9ab7-b096e19f3a56",
+ "name": "view-consent",
+ "description": "${role_view-consent}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6c7757f2-9ed7-4609-8e41-f4316ca8d31e",
+ "attributes": {}
+ },
+ {
+ "id": "8eb01f07-3771-4b28-ab78-6f216079b508",
+ "name": "view-profile",
+ "description": "${role_view-profile}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6c7757f2-9ed7-4609-8e41-f4316ca8d31e",
+ "attributes": {}
+ },
+ {
+ "id": "23954dae-8150-4183-8733-bce1349fb0ec",
+ "name": "manage-account-links",
+ "description": "${role_manage-account-links}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6c7757f2-9ed7-4609-8e41-f4316ca8d31e",
+ "attributes": {}
+ },
+ {
+ "id": "734d080d-1f67-48e9-942f-9233f6eca901",
+ "name": "view-applications",
+ "description": "${role_view-applications}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6c7757f2-9ed7-4609-8e41-f4316ca8d31e",
+ "attributes": {}
+ }
+ ]
+ }
+ },
+ "groups": [],
+ "defaultRole": {
+ "id": "0825e37b-b5bb-413d-9c1c-23457f17cb66",
+ "name": "default-roles-REALM_NAME_PLACEHOLDER",
+ "description": "${role_default-roles}",
+ "composite": true,
+ "clientRole": false,
+ "containerId": "REALM_NAME_PLACEHOLDER"
+ },
+ "requiredCredentials": [
+ "password"
+ ],
+ "otpPolicyType": "totp",
+ "otpPolicyAlgorithm": "HmacSHA1",
+ "otpPolicyInitialCounter": 0,
+ "otpPolicyDigits": 6,
+ "otpPolicyLookAheadWindow": 1,
+ "otpPolicyPeriod": 30,
+ "otpSupportedApplications": [
+ "FreeOTP",
+ "Google Authenticator"
+ ],
+ "webAuthnPolicyRpEntityName": "keycloak",
+ "webAuthnPolicySignatureAlgorithms": [
+ "ES256"
+ ],
+ "webAuthnPolicyRpId": "",
+ "webAuthnPolicyAttestationConveyancePreference": "not specified",
+ "webAuthnPolicyAuthenticatorAttachment": "not specified",
+ "webAuthnPolicyRequireResidentKey": "not specified",
+ "webAuthnPolicyUserVerificationRequirement": "not specified",
+ "webAuthnPolicyCreateTimeout": 0,
+ "webAuthnPolicyAvoidSameAuthenticatorRegister": false,
+ "webAuthnPolicyAcceptableAaguids": [],
+ "webAuthnPolicyPasswordlessRpEntityName": "keycloak",
+ "webAuthnPolicyPasswordlessSignatureAlgorithms": [
+ "ES256"
+ ],
+ "webAuthnPolicyPasswordlessRpId": "",
+ "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
+ "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
+ "webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
+ "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
+ "webAuthnPolicyPasswordlessCreateTimeout": 0,
+ "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
+ "webAuthnPolicyPasswordlessAcceptableAaguids": [],
+ "scopeMappings": [
+ {
+ "clientScope": "offline_access",
+ "roles": [
+ "offline_access"
+ ]
+ }
+ ],
+ "clientScopeMappings": {
+ "account": [
+ {
+ "client": "account-console",
+ "roles": [
+ "manage-account"
+ ]
+ }
+ ]
+ },
+ "clients": [
+ {
+ "id": "6c7757f2-9ed7-4609-8e41-f4316ca8d31e",
+ "clientId": "account",
+ "name": "${client_account}",
+ "rootUrl": "${authBaseUrl}",
+ "baseUrl": "/realms/REALM_NAME_PLACEHOLDER/account/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/realms/REALM_NAME_PLACEHOLDER/account/*"
+ ],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "post.logout.redirect.uris": "+"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "fe6ddaaf-3a90-4942-ae6a-1f170c87fc3b",
+ "clientId": "account-console",
+ "name": "${client_account-console}",
+ "rootUrl": "${authBaseUrl}",
+ "baseUrl": "/realms/REALM_NAME_PLACEHOLDER/account/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/realms/REALM_NAME_PLACEHOLDER/account/*"
+ ],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "post.logout.redirect.uris": "+",
+ "pkce.code.challenge.method": "S256"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "protocolMappers": [
+ {
+ "id": "9f385a11-7b42-4f92-ac9b-7d286590a392",
+ "name": "audience resolve",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-resolve-mapper",
+ "consentRequired": false,
+ "config": {}
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "61ecc83e-d3f3-4b4f-a821-845094b3d9d4",
+ "clientId": "admin-cli",
+ "name": "${client_admin-cli}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": false,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": true,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "6eed48a3-64bd-48ed-ac7c-607f8e724258",
+ "clientId": "broker",
+ "name": "${client_broker}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": true,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "631f9fd2-7539-4190-8983-0e94614c5b73",
+ "clientId": "realm-management",
+ "name": "${client_realm-management}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": true,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "05f3367b-492b-40e1-ba0c-f000aa3ad0ef",
+ "clientId": "security-admin-console",
+ "name": "${client_security-admin-console}",
+ "rootUrl": "${authAdminUrl}",
+ "baseUrl": "/admin/REALM_NAME_PLACEHOLDER/console/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/admin/REALM_NAME_PLACEHOLDER/console/*"
+ ],
+ "webOrigins": [
+ "+"
+ ],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "post.logout.redirect.uris": "+",
+ "pkce.code.challenge.method": "S256"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "protocolMappers": [
+ {
+ "id": "9d1f5814-fa63-4c36-ae10-747d30f47c69",
+ "name": "locale",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "locale",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "locale",
+ "jsonType.label": "String"
+ }
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ }
+ ],
+ "clientScopes": [
+ {
+ "id": "23fc5623-9366-478f-9924-801d71f32489",
+ "name": "role_list",
+ "description": "SAML role list",
+ "protocol": "saml",
+ "attributes": {
+ "consent.screen.text": "${samlRoleListScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "31541a2f-1c88-43d9-96fe-9f9efbd096d4",
+ "name": "role list",
+ "protocol": "saml",
+ "protocolMapper": "saml-role-list-mapper",
+ "consentRequired": false,
+ "config": {
+ "single": "false",
+ "attribute.nameformat": "Basic",
+ "attribute.name": "Role"
+ }
+ }
+ ]
+ },
+ {
+ "id": "1859a4f3-d051-4800-963f-45b624cccd57",
+ "name": "web-origins",
+ "description": "OpenID Connect scope for add allowed web origins to the access token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "false",
+ "consent.screen.text": ""
+ },
+ "protocolMappers": [
+ {
+ "id": "a7777bff-a046-4fe3-a5a9-a520d79865ec",
+ "name": "allowed web origins",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-allowed-origins-mapper",
+ "consentRequired": false,
+ "config": {}
+ }
+ ]
+ },
+ {
+ "id": "7d011629-d7f1-45ad-a09b-b4decb3d47ed",
+ "name": "acr",
+ "description": "OpenID Connect scope for add acr (authentication context class reference) to the token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "false"
+ },
+ "protocolMappers": [
+ {
+ "id": "22a74f8c-4493-4a1a-bf97-f51466e336b3",
+ "name": "acr loa level",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-acr-mapper",
+ "consentRequired": false,
+ "config": {
+ "id.token.claim": "true",
+ "access.token.claim": "true"
+ }
+ }
+ ]
+ },
+ {
+ "id": "7fb8529d-cb6f-4f31-b4c3-f6be6f74b47d",
+ "name": "phone",
+ "description": "OpenID Connect built-in scope: phone",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${phoneScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "5bd8bfba-d8a3-4792-aaec-5f0513397193",
+ "name": "phone number verified",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "phoneNumberVerified",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "phone_number_verified",
+ "jsonType.label": "boolean"
+ }
+ },
+ {
+ "id": "89146d36-28d5-4750-933e-75014b203dcf",
+ "name": "phone number",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "phoneNumber",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "phone_number",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "01025c61-c655-463d-967d-a45e88368472",
+ "name": "roles",
+ "description": "OpenID Connect scope for add user roles to the access token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${rolesScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "ad80bcc7-66d4-44c0-b34e-65822a57359a",
+ "name": "realm roles",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-realm-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "foo",
+ "access.token.claim": "true",
+ "claim.name": "realm_access.roles",
+ "jsonType.label": "String",
+ "multivalued": "true"
+ }
+ },
+ {
+ "id": "73346462-e569-4679-a57d-fe623bdc5a95",
+ "name": "audience resolve",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-resolve-mapper",
+ "consentRequired": false,
+ "config": {}
+ },
+ {
+ "id": "3842db0a-837f-4564-9e48-07c87f5d3258",
+ "name": "client roles",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-client-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "foo",
+ "access.token.claim": "true",
+ "claim.name": "resource_access.${client_id}.roles",
+ "jsonType.label": "String",
+ "multivalued": "true"
+ }
+ }
+ ]
+ },
+ {
+ "id": "f79aab58-4d4a-40ee-b879-a586ff956f12",
+ "name": "microprofile-jwt",
+ "description": "Microprofile - JWT built-in scope",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "false"
+ },
+ "protocolMappers": [
+ {
+ "id": "ccb6bedc-b921-4c83-abe6-13de8c0e9795",
+ "name": "groups",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-realm-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "multivalued": "true",
+ "user.attribute": "foo",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "groups",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "19ae8192-0189-4644-a362-d08a0bce5680",
+ "name": "upn",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "username",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "upn",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "a0d6d0c2-afd3-4b29-a99f-ff3002866519",
+ "name": "offline_access",
+ "description": "OpenID Connect built-in scope: offline_access",
+ "protocol": "openid-connect",
+ "attributes": {
+ "consent.screen.text": "${offlineAccessScopeConsentText}",
+ "display.on.consent.screen": "true"
+ }
+ },
+ {
+ "id": "1dcbfe97-e4ab-4df7-8517-4eaaa26ea410",
+ "name": "profile",
+ "description": "OpenID Connect built-in scope: profile",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${profileScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "8448e164-b72e-406e-b14b-ae5d1e72393a",
+ "name": "gender",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "gender",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "gender",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "c573ae92-f94a-494e-9403-f875d22d3e8d",
+ "name": "profile",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "profile",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "profile",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "09f992cc-2d64-4d4d-88ca-59a1b63325e9",
+ "name": "website",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "website",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "website",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "04658d90-dc3d-4865-ac52-6f16570fcd76",
+ "name": "full name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-full-name-mapper",
+ "consentRequired": false,
+ "config": {
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "userinfo.token.claim": "true"
+ }
+ },
+ {
+ "id": "de199ca1-e720-419f-aeee-e112568f5cff",
+ "name": "family name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "lastName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "family_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "08daf912-8959-4ba5-9c38-ffcd395d6487",
+ "name": "given name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "firstName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "given_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "d76e56a2-6237-46d5-a56b-0ecd1f979e85",
+ "name": "username",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "username",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "preferred_username",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "6bc40007-ab16-48f6-ae81-a66a9062ad5c",
+ "name": "picture",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "picture",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "picture",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "0385dbe8-587c-49ab-a317-a15b5b52d456",
+ "name": "zoneinfo",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "zoneinfo",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "zoneinfo",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "28946b3e-0eab-44a5-8eee-d42088072306",
+ "name": "locale",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "locale",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "locale",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "e61c48dc-d083-4029-92d1-3c7a6f3d8bb9",
+ "name": "birthdate",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "birthdate",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "birthdate",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "62545d7c-ef2e-48a6-bff8-e2e9a2b16c3d",
+ "name": "middle name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "middleName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "middle_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "f1c75501-26b2-4d94-82aa-851e4fa3dd7c",
+ "name": "nickname",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "nickname",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "nickname",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "046a0b0d-5256-48fe-9b8f-b5193d87ebdd",
+ "name": "updated at",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "updatedAt",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "updated_at",
+ "jsonType.label": "long"
+ }
+ }
+ ]
+ },
+ {
+ "id": "d807e61e-3661-44ff-a8cd-285458e6f763",
+ "name": "address",
+ "description": "OpenID Connect built-in scope: address",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${addressScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "fede614b-c46e-484c-8dba-9590cd0205fe",
+ "name": "address",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-address-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute.formatted": "formatted",
+ "user.attribute.country": "country",
+ "user.attribute.postal_code": "postal_code",
+ "userinfo.token.claim": "true",
+ "user.attribute.street": "street",
+ "id.token.claim": "true",
+ "user.attribute.region": "region",
+ "access.token.claim": "true",
+ "user.attribute.locality": "locality"
+ }
+ }
+ ]
+ },
+ {
+ "id": "c8a4b7a9-c8ba-412b-a17d-e90a3c6393fd",
+ "name": "email",
+ "description": "OpenID Connect built-in scope: email",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${emailScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "de4bafae-e88c-4c2f-9001-311f5c141633",
+ "name": "email",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "email",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "email",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "9aa11aac-4178-435b-83b3-2d85508e34bd",
+ "name": "email verified",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "emailVerified",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "email_verified",
+ "jsonType.label": "boolean"
+ }
+ }
+ ]
+ }
+ ],
+ "defaultDefaultClientScopes": [
+ "role_list",
+ "profile",
+ "email",
+ "roles",
+ "web-origins",
+ "acr"
+ ],
+ "defaultOptionalClientScopes": [
+ "offline_access",
+ "address",
+ "phone",
+ "microprofile-jwt"
+ ],
+ "browserSecurityHeaders": {
+ "contentSecurityPolicyReportOnly": "",
+ "xContentTypeOptions": "nosniff",
+ "xRobotsTag": "none",
+ "xFrameOptions": "SAMEORIGIN",
+ "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+ "xXSSProtection": "1; mode=block",
+ "strictTransportSecurity": "max-age=31536000; includeSubDomains"
+ },
+ "smtpServer": {},
+ "eventsEnabled": false,
+ "eventsListeners": [
+ "jboss-logging"
+ ],
+ "enabledEventTypes": [],
+ "adminEventsEnabled": false,
+ "adminEventsDetailsEnabled": false,
+ "identityProviders": [],
+ "identityProviderMappers": [],
+ "components": {
+ "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [
+ {
+ "id": "808ef7c4-b5d1-491c-ade0-559f38287e68",
+ "name": "Full Scope Disabled",
+ "providerId": "scope",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {}
+ },
+ {
+ "id": "2a0ad1a6-d6f9-43cb-8ec1-8913a23339d7",
+ "name": "Allowed Protocol Mapper Types",
+ "providerId": "allowed-protocol-mappers",
+ "subType": "authenticated",
+ "subComponents": {},
+ "config": {
+ "allowed-protocol-mapper-types": [
+ "saml-role-list-mapper",
+ "oidc-full-name-mapper",
+ "oidc-usermodel-property-mapper",
+ "oidc-address-mapper",
+ "oidc-usermodel-attribute-mapper",
+ "saml-user-attribute-mapper",
+ "oidc-sha256-pairwise-sub-mapper",
+ "saml-user-property-mapper"
+ ]
+ }
+ },
+ {
+ "id": "3695208c-32af-497b-9af9-5de878749899",
+ "name": "Consent Required",
+ "providerId": "consent-required",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {}
+ },
+ {
+ "id": "b7317013-6157-4099-a1ee-194df4808b2d",
+ "name": "Allowed Client Scopes",
+ "providerId": "allowed-client-templates",
+ "subType": "authenticated",
+ "subComponents": {},
+ "config": {
+ "allow-default-scopes": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "2464d485-980d-447a-94e2-34cf96aad1f1",
+ "name": "Allowed Client Scopes",
+ "providerId": "allowed-client-templates",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "allow-default-scopes": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "6460fb5a-bbb9-400b-aba7-85cbe8666341",
+ "name": "Trusted Hosts",
+ "providerId": "trusted-hosts",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "host-sending-registration-request-must-match": [
+ "true"
+ ],
+ "client-uris-must-match": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "c2093410-4c63-4436-9294-535c492912dc",
+ "name": "Allowed Protocol Mapper Types",
+ "providerId": "allowed-protocol-mappers",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "allowed-protocol-mapper-types": [
+ "oidc-usermodel-property-mapper",
+ "oidc-sha256-pairwise-sub-mapper",
+ "saml-role-list-mapper",
+ "saml-user-property-mapper",
+ "oidc-address-mapper",
+ "saml-user-attribute-mapper",
+ "oidc-usermodel-attribute-mapper",
+ "oidc-full-name-mapper"
+ ]
+ }
+ },
+ {
+ "id": "f9ef3de5-1ad1-4c9c-92bd-62a070e13ba2",
+ "name": "Max Clients Limit",
+ "providerId": "max-clients",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "max-clients": [
+ "200"
+ ]
+ }
+ }
+ ],
+ "org.keycloak.keys.KeyProvider": [
+ {
+ "id": "d75363d0-aed5-4fea-a97f-d0c1adb4fa63",
+ "name": "hmac-generated",
+ "providerId": "hmac-generated",
+ "subComponents": {},
+ "config": {
+ "kid": [
+ "ea50f128-6340-4f3e-8050-1e79ba559121"
+ ],
+ "secret": [
+ "QYJipEnEXtsqk2OqtX1oyyQrANj03UWaGGf1p4yD28-x4MMOSxXVpEVTwZZvpgJeB-4L2lztTaJxVhANSO1lDQ"
+ ],
+ "priority": [
+ "100"
+ ],
+ "algorithm": [
+ "HS256"
+ ]
+ }
+ },
+ {
+ "id": "594b0771-b860-4aa8-8a81-4b29ee5ac384",
+ "name": "rsa-generated",
+ "providerId": "rsa-generated",
+ "subComponents": {},
+ "config": {
+ "privateKey": [
+ "MIIEowIBAAKCAQEAsZSMHIVGaorVvBfVYzTAHzXO7/ilxcjty/hayFAB3C1CkEnKeYIs2hUv8s3DFrG26GBFRWI+HVX8yCCuwksDkF4kB6ZxpNV/NCwt4+Hv1Fr/A58eVHkriXajlOE9LUkvrSd04bGGD+SplAgCweQzVcHF5Iy4bvsIJ8ow5WKJ7dGtJlnU2ddBEdja2KhlFWBdqn2YCdvpuLGEYNGr5/ANBM6evcv/bU3tVdq64TPSC13kw/QicKzAU6H+4k8reIAgaEhtudqb6sWI9G0JiSPtb98psTZMFjoGb9yphOFsoSmljA3Ozp2wDVltV/zyk8Aw7J2I8EOCdjcX8BdkkQc6oQIDAQABAoIBABEdhJ2RGNbW97+vumDb6jJ34LCPUgbslULF9pX85BkBAbvfaNTqP4FrblokC8wJp9vgv3xu+hagvYLaZ42RZlAJSsaz+5sL+r0gDvI6Sf+5H4ANW4J/xTr0BNMqHFfbiG1Tcrf4ALhSbSe31/AxGuOGkBi1mWcU6dXP7oOFSk7x79FVmirB0bKGGwd2TNbrmtBSiDU33vUPxwGnDSsmw8TVHyjISiM0BfvVkS9RrBGqEnNm0iKccukRgengrqCK8D4fq65YPrQQQ9o9I50eU0qHoCiVJyNC2+MBpiOniShLO8jyiLAuhDKDfoKis5C6Hqm1yyf2PzwB1rIjV5XVf2ECgYEA6JiWMHHKfyR3QNvGjRp3Jfz/WQvLGXZCwVDowhlNRtfvGC56tEC+QAWxM/4l12u1NMyYSDeF44tYpzq0dGtVkTWTzQKNczTkGhValNMgFEUa8pwumBVVfrfLllA0VGrMW6fEAr8ta2gFODOWoViLSD0s0Jmu6CpdKSUzafcnMjkCgYEAw3LQ2sLgGL8LajjPl++LgWcKRZF3M80IFF2fE78I80zVow4x6Ei+EyrvObmJ5necXKkRA7o7h/7Xb+ATy2h0ZCdr/OXpmR/yGASfUdNXDrtQ0nYF6TNz1Xqadi9cGv7YKy8SOgbB0SM5S6aRy+ouoaUwNCSsWDleAgEOQvpzq6kCgYBrPv/xMmaWHTBHXY69PPi3MWJjooZxJRA+ppnL9XKmOaZq1fOJ7VhLmNRODt9P5r/UqomEsuUvN+8WnIDcNSltHPEbVBP4jOioBjSP7pEaB4sXVmA9i4iyNvjORAj864lysXY1dgTxQzM06MSJfJQsKNjjDhmRvwbZk+eS8nzGMQKBgAFjAipbMZ3bVShmyMpKL9I2OfNuacsbTFBgra1FMLoRNH7Yre/4/ChEqLffIiRZeumJZY6CNsPrQfoQO/O4hQLk6LY9p1+nw176QWsiNb7sA1HK9pXGAK9mFEx8X4ntfvknd1ikDaH/PvvTbbtlqPkKpAHqtLJXjdwzx7cf8cwpAoGBALxwuNYA7NBV8qRzTsLfSGoZEfl6jQogD3GR+EmFswIEYzdp8Mp+VwcpBjP5D28v9kFKa8dCe7TU9aY1JZm5W+N3ZqfhLp6TNepKVpRsyKsF4Pjz9fDZu1Q9AU81ImSO4w6FkLqQc069w7M5O/tT4/WjYbfqEp16UkP77Gh1F4O6"
+ ],
+ "keyUse": [
+ "SIG"
+ ],
+ "certificate": [
+ "MIIClzCCAX8CBgGEV1OLDTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARkZW1vMB4XDTIyMTEwODEyNTgyM1oXDTMyMTEwODEzMDAwM1owDzENMAsGA1UEAwwEZGVtbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALGUjByFRmqK1bwX1WM0wB81zu/4pcXI7cv4WshQAdwtQpBJynmCLNoVL/LNwxaxtuhgRUViPh1V/MggrsJLA5BeJAemcaTVfzQsLePh79Ra/wOfHlR5K4l2o5ThPS1JL60ndOGxhg/kqZQIAsHkM1XBxeSMuG77CCfKMOViie3RrSZZ1NnXQRHY2tioZRVgXap9mAnb6bixhGDRq+fwDQTOnr3L/21N7VXauuEz0gtd5MP0InCswFOh/uJPK3iAIGhIbbnam+rFiPRtCYkj7W/fKbE2TBY6Bm/cqYThbKEppYwNzs6dsA1ZbVf88pPAMOydiPBDgnY3F/AXZJEHOqECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAdo+c58iEquMpcBiMQ44lhSnroyrRwHazMxQ/8fHUUh2QxNwlGynGPfhMNyUtn06sPZqabV1ixTDfb6NbEpJK/HN3meWUNl4I4i5Zabew5DuUCh/BLRUbgOApsoRyHabDlR68inuXIPaP4M8lOfQsZO2/xNuGnr/eedKIR1WotXtmm2WJv79A9tJQkplizS78HoCa+HlyP1UAuAUDO0IZsJwY8CbKq1wgrhs9by8amdzZRBVILuDnuqEqeRxSY4o4BOvtM7TG5aA0iBVQc473NT1IvY10ojW6zs/ahqs0yG44+W2aBG35DvoDNVqP9Lw1vaTAD7OHdzQGhREz07cemA=="
+ ],
+ "priority": [
+ "100"
+ ]
+ }
+ },
+ {
+ "id": "da244786-6bf6-40c4-b7c3-094f883d969e",
+ "name": "aes-generated",
+ "providerId": "aes-generated",
+ "subComponents": {},
+ "config": {
+ "kid": [
+ "6ee413ed-3b74-458f-acb7-a89d5e05f0b9"
+ ],
+ "secret": [
+ "sANwaoZOUoMcaPlAr5U1sQ"
+ ],
+ "priority": [
+ "100"
+ ]
+ }
+ },
+ {
+ "id": "1eeba879-03e8-4aad-b91a-0159cf513d73",
+ "name": "rsa-enc-generated",
+ "providerId": "rsa-enc-generated",
+ "subComponents": {},
+ "config": {
+ "privateKey": [
+ "MIIEowIBAAKCAQEA4FmIA8jfFAMVm8BuINWDWCn//Xzlk48yoUly1kP8RXriGOYfXrQQTqae0nhBBqlaJFBXAjI41UGJE9+4j23/aGp8vcTTUy9M4qBl9jlt9Pqz178/KaMDuBkeb3TV8PbR6PXrCSuWOuT3LJaXWEitpeMM/+dFSOxD4M1LWOwoQltSlmiZblcb5NsRal60sHvFUA5ecp35jW7Rj+xAQKR7QxgOr8rf83P9NPWYww4+lbKdbgnD2IMfdzZ9soSiHX4WtRrl1dPAqnihfEeaOoDXXTa1m49Q4xORnMVs6E15A+Zviu0xhR1385GT7sHLhZbSh+oLH4nx9jFinry+AgGlUwIDAQABAoIBABbvIBfe82r8y7sxxzBFE1myZXBY0bEtbMwPEZW0unex0aYg9Cj+uEIKB2dVkrQnIMdgjRx03Nl0CxrEfn3vDTJz3E+b7Mxuo+nw4qtygHqQHE1cSA0uFGW/75wOMgahfKDXbtDvqzpXCKt+s3b7awDvvnb0geEsAd5bri2napApy7qEg8iD04NhJhPj+nnoZ/jWTs3N++Dy/a0Y4/TsmIJXjtOY4JUcbYSJDBgFW0hikU/JKRMYXRZNCOzgDlUO+ejxKR2/HJjNK3ynf8Z5seROvVLI6sDTAA20b/PQLW4yEC7BtjWor8zag5tN6ZORdf4tZrsWLAiSAU2NPZepRx0CgYEA9duql4nPIs9Vf7GBZeVJd8Vl5z4WuAbaLgZ0TxaUwU83b9oaw1JmQgZ7gOCDgBkdECJk7iZAgdCCDKyFZyq+aeE8jn2uWXXrh/nMw2rXtAu3K464oyN2kWd4d7vinEsm7B5Vz1tiT20uuACS8AWi63pdBsx7yIsoq/yTantSMN0CgYEA6Zq7A++W2vwCWf0bzuwZ8ozObHafr3awgnEzlD2CXUW0mBC3ptxbo9+ug9SnZC7UMVNEqTVArd2mFZYEnDZGvGbsiN7Qnfw3foKdNpvxMP+CfuQw7vxmCa1JOd5nLz6zKBEPGjIuCy0+wB6ASpUQNxUQQkQoC7L8Qt5cysUSM+8CgYAiSM6iMSp8bTM8ClHEFtRG6nUKaSMb6IC2WFoRyVFXH6fYZi7DPBNcc7D3SNetnlLqNBGlEBqAv8XS5J/5wgEpnKooKKiOex4sKQ5/1b9csSGK5m0i+sgHAMnQ0JeKOgSkepp2vwSXlN8l85aJ+A8/DSI513wPfDBgw2j/OVE91QKBgCnanTNBVAf8Kvewj7DtQGDitYFdZ5LqcwmL+q/OrXLEsGymYiE1Tf34b64TBcK/WSlVP/IJJoOAOOeZL05FszrCPhLvyPTlYZP7FuvX2MjsnpbZj6Lh+e416+7AWEBwvWyqUchhwTojayDE1juGpZcY4Qbea0ZdVTEt4fY6hN5lAoGBAIjrfcjMELZqlLEECwjvTgPmYqTgyJKgVw/SrYBvPpNNqVeIwb62FK19BjXuoIjecXBX8jvefGNa6qTw/OjZLk7JNNbbOdJ1PFp8GkD+e0PPUoISSY0+rAq77geLLfZbcZUwoE0UqKwSYcz0w549aUVKc/5x3tHOxEb7UcWWS5DY"
+ ],
+ "keyUse": [
+ "ENC"
+ ],
+ "certificate": [
+ "MIIClzCCAX8CBgGEV1OMBzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARkZW1vMB4XDTIyMTEwODEyNTgyM1oXDTMyMTEwODEzMDAwM1owDzENMAsGA1UEAwwEZGVtbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOBZiAPI3xQDFZvAbiDVg1gp//185ZOPMqFJctZD/EV64hjmH160EE6mntJ4QQapWiRQVwIyONVBiRPfuI9t/2hqfL3E01MvTOKgZfY5bfT6s9e/PymjA7gZHm901fD20ej16wkrljrk9yyWl1hIraXjDP/nRUjsQ+DNS1jsKEJbUpZomW5XG+TbEWpetLB7xVAOXnKd+Y1u0Y/sQECke0MYDq/K3/Nz/TT1mMMOPpWynW4Jw9iDH3c2fbKEoh1+FrUa5dXTwKp4oXxHmjqA1102tZuPUOMTkZzFbOhNeQPmb4rtMYUdd/ORk+7By4WW0ofqCx+J8fYxYp68vgIBpVMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAwPwABXVkSlRYqA9sMKJrw9piGH8tkwf6wQeAFhQsInbDzXLeuLt0A3gSuh5nL2zOGcxXddIK4IgUSqI+DlFlFsSkVqHFrQBAdIVRXsYFvGbARKhVuInHlpaOy6Y/VC6opL1BnqsmUOPEv7pk4Nhf/z7y5yZfTUaGiD+K1KA/mEf56NytOFJYsxiCZaAGX6BYIavRJp3YKPAcsNlJS//1G4meOlYcx5HiTA+qY/spc7vPeKuowSh3v26x4tgypLqoD0BAS5KrK4PEVaQM0IcBC3jrIY+7dGbE1Z374nm+1FDU7md48TJdI0c75r60cpBnHUH2bLJo2Z0ezrEojP6mvQ=="
+ ],
+ "priority": [
+ "100"
+ ],
+ "algorithm": [
+ "RSA-OAEP"
+ ]
+ }
+ }
+ ]
+ },
+ "internationalizationEnabled": false,
+ "supportedLocales": [],
+ "authenticationFlows": [
+ {
+ "id": "95570b1f-da9e-42a0-9532-aa9b690b04cb",
+ "alias": "Account verification options",
+ "description": "Method with which to verity the existing account",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-email-verification",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Verify Existing Account by Re-authentication",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "854f25b9-b37b-468a-b8ac-1e0da29133ba",
+ "alias": "Authentication Options",
+ "description": "Authentication options.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "basic-auth",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "basic-auth-otp",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-spnego",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 30,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "ebcd0954-f08f-4c69-970e-43569320bb07",
+ "alias": "Browser - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-otp-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "cd4b03ca-1a0f-4a9b-8bd9-388e0459d7ac",
+ "alias": "Direct Grant - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "direct-grant-validate-otp",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "692bd371-d43a-440b-886b-2a0884dd5b9f",
+ "alias": "First broker login - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-otp-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "dce38371-4f6b-45d1-94b0-5e91182c31fd",
+ "alias": "Handle Existing Account",
+ "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-confirm-link",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Account verification options",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "357541a3-2499-42da-9ef0-db129f38f39b",
+ "alias": "Reset - Conditional OTP",
+ "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "reset-otp",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "9c37a124-af5e-44a2-b619-b3a88e1033c6",
+ "alias": "User creation or linking",
+ "description": "Flow for the existing/non-existing user alternatives",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticatorConfig": "create unique user config",
+ "authenticator": "idp-create-user-if-unique",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Handle Existing Account",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "94355d8f-b66f-405d-80e5-55ec030fb18c",
+ "alias": "Verify Existing Account by Re-authentication",
+ "description": "Reauthentication of existing account",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-username-password-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "First broker login - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "8fcdac85-ec7e-4a3b-908a-4f00978d4724",
+ "alias": "browser",
+ "description": "browser based authentication",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "auth-cookie",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-spnego",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "identity-provider-redirector",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 25,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 30,
+ "autheticatorFlow": true,
+ "flowAlias": "forms",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "cd9ce79e-ba0b-4d58-8249-40f8b2139a56",
+ "alias": "clients",
+ "description": "Base authentication for clients",
+ "providerId": "client-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "client-secret",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "client-jwt",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "client-secret-jwt",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 30,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "client-x509",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 40,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "40f9ac10-edc0-46a6-b020-ba1785199911",
+ "alias": "direct grant",
+ "description": "OpenID Connect Resource Owner Grant",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "direct-grant-validate-username",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "direct-grant-validate-password",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 30,
+ "autheticatorFlow": true,
+ "flowAlias": "Direct Grant - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "0ac19480-8675-4679-b222-64508c62bcdb",
+ "alias": "docker auth",
+ "description": "Used by Docker clients to authenticate against the IDP",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "docker-http-basic-authenticator",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "9fd2aa99-79d7-435b-a852-5c18fad28546",
+ "alias": "first broker login",
+ "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticatorConfig": "review profile config",
+ "authenticator": "idp-review-profile",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "User creation or linking",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "da0a8a3d-9643-4746-b42d-2e8c915f76e7",
+ "alias": "forms",
+ "description": "Username, password, otp and other auth forms.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "auth-username-password-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Browser - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "5eea7962-6fe5-4b69-8401-313afd0f6559",
+ "alias": "http challenge",
+ "description": "An authentication flow based on challenge-response HTTP Authentication Schemes",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "no-cookie-redirect",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Authentication Options",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "f80d7c69-9314-4f4b-a61a-28a73e2d0879",
+ "alias": "registration",
+ "description": "registration flow",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "registration-page-form",
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": true,
+ "flowAlias": "registration form",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "deffbcd6-aa05-40e2-9bca-2ed50be54bd6",
+ "alias": "registration form",
+ "description": "registration form",
+ "providerId": "form-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "registration-user-creation",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "registration-profile-action",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 40,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "registration-password-action",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 50,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "registration-recaptcha-action",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 60,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "0b06e91d-77f8-4d8e-a55b-21caf478524a",
+ "alias": "reset credentials",
+ "description": "Reset credentials for a user if they forgot their password or something",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "reset-credentials-choose-user",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "reset-credential-email",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "reset-password",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 30,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 40,
+ "autheticatorFlow": true,
+ "flowAlias": "Reset - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "d51e394a-e9a8-495b-ac30-3adb1e66a369",
+ "alias": "saml ecp",
+ "description": "SAML ECP Profile Authentication Flow",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "http-basic-authenticator",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ }
+ ],
+ "authenticatorConfig": [
+ {
+ "id": "3c1657ce-3153-4718-bbec-9d0c508eb8a8",
+ "alias": "create unique user config",
+ "config": {
+ "require.password.update.after.registration": "false"
+ }
+ },
+ {
+ "id": "70a33e93-226e-492e-b119-f164e2cc457b",
+ "alias": "review profile config",
+ "config": {
+ "update.profile.on.first.login": "missing"
+ }
+ }
+ ],
+ "requiredActions": [
+ {
+ "alias": "CONFIGURE_TOTP",
+ "name": "Configure OTP",
+ "providerId": "CONFIGURE_TOTP",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 10,
+ "config": {}
+ },
+ {
+ "alias": "terms_and_conditions",
+ "name": "Terms and Conditions",
+ "providerId": "terms_and_conditions",
+ "enabled": false,
+ "defaultAction": false,
+ "priority": 20,
+ "config": {}
+ },
+ {
+ "alias": "UPDATE_PASSWORD",
+ "name": "Update Password",
+ "providerId": "UPDATE_PASSWORD",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 30,
+ "config": {}
+ },
+ {
+ "alias": "UPDATE_PROFILE",
+ "name": "Update Profile",
+ "providerId": "UPDATE_PROFILE",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 40,
+ "config": {}
+ },
+ {
+ "alias": "VERIFY_EMAIL",
+ "name": "Verify Email",
+ "providerId": "VERIFY_EMAIL",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 50,
+ "config": {}
+ },
+ {
+ "alias": "delete_account",
+ "name": "Delete Account",
+ "providerId": "delete_account",
+ "enabled": false,
+ "defaultAction": false,
+ "priority": 60,
+ "config": {}
+ },
+ {
+ "alias": "webauthn-register",
+ "name": "Webauthn Register",
+ "providerId": "webauthn-register",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 70,
+ "config": {}
+ },
+ {
+ "alias": "webauthn-register-passwordless",
+ "name": "Webauthn Register Passwordless",
+ "providerId": "webauthn-register-passwordless",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 80,
+ "config": {}
+ },
+ {
+ "alias": "update_user_locale",
+ "name": "Update User Locale",
+ "providerId": "update_user_locale",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 1000,
+ "config": {}
+ }
+ ],
+ "browserFlow": "browser",
+ "registrationFlow": "registration",
+ "directGrantFlow": "direct grant",
+ "resetCredentialsFlow": "reset credentials",
+ "clientAuthenticationFlow": "clients",
+ "dockerAuthenticationFlow": "docker auth",
+ "attributes": {
+ "cibaBackchannelTokenDeliveryMode": "poll",
+ "cibaExpiresIn": "120",
+ "cibaAuthRequestedUserHint": "login_hint",
+ "oauth2DeviceCodeLifespan": "600",
+ "oauth2DevicePollingInterval": "5",
+ "parRequestUriLifespan": "60",
+ "cibaInterval": "5"
+ },
+ "keycloakVersion": "19.0.3",
+ "userManagedAccessAllowed": false,
+ "clientProfiles": {
+ "profiles": []
+ },
+ "clientPolicies": {
+ "policies": []
+ }
+}
diff --git a/src/main/resources/baseline/20.0.3/client/client.json b/src/main/resources/baseline/20.0.3/client/client.json
new file mode 100644
index 000000000..d555d4f48
--- /dev/null
+++ b/src/main/resources/baseline/20.0.3/client/client.json
@@ -0,0 +1,45 @@
+{
+ "id": "8a641514-bb92-4a5e-8ea4-27b90ef3e637",
+ "clientId": "reference-client",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "hzjJYnHVxMf3I3ugD4le0CgT1iI3rCx2",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "client.secret.creation.time": "1676457441"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": true,
+ "nodeReRegistrationTimeout": -1,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ],
+ "access": {
+ "view": true,
+ "configure": true,
+ "manage": true
+ }
+}
diff --git a/src/main/resources/baseline/20.0.3/realm/realm.json b/src/main/resources/baseline/20.0.3/realm/realm.json
new file mode 100644
index 000000000..ee28d9e47
--- /dev/null
+++ b/src/main/resources/baseline/20.0.3/realm/realm.json
@@ -0,0 +1,2188 @@
+{
+ "id": "REALM_NAME_PLACEHOLDER",
+ "realm": "REALM_NAME_PLACEHOLDER",
+ "notBefore": 0,
+ "defaultSignatureAlgorithm": "RS256",
+ "revokeRefreshToken": false,
+ "refreshTokenMaxReuse": 0,
+ "accessTokenLifespan": 300,
+ "accessTokenLifespanForImplicitFlow": 900,
+ "ssoSessionIdleTimeout": 1800,
+ "ssoSessionMaxLifespan": 36000,
+ "ssoSessionIdleTimeoutRememberMe": 0,
+ "ssoSessionMaxLifespanRememberMe": 0,
+ "offlineSessionIdleTimeout": 2592000,
+ "offlineSessionMaxLifespanEnabled": false,
+ "offlineSessionMaxLifespan": 5184000,
+ "clientSessionIdleTimeout": 0,
+ "clientSessionMaxLifespan": 0,
+ "clientOfflineSessionIdleTimeout": 0,
+ "clientOfflineSessionMaxLifespan": 0,
+ "accessCodeLifespan": 60,
+ "accessCodeLifespanUserAction": 300,
+ "accessCodeLifespanLogin": 1800,
+ "actionTokenGeneratedByAdminLifespan": 43200,
+ "actionTokenGeneratedByUserLifespan": 300,
+ "oauth2DeviceCodeLifespan": 600,
+ "oauth2DevicePollingInterval": 5,
+ "enabled": true,
+ "sslRequired": "external",
+ "registrationAllowed": false,
+ "registrationEmailAsUsername": false,
+ "rememberMe": false,
+ "verifyEmail": false,
+ "loginWithEmailAllowed": true,
+ "duplicateEmailsAllowed": false,
+ "resetPasswordAllowed": false,
+ "editUsernameAllowed": false,
+ "bruteForceProtected": false,
+ "permanentLockout": false,
+ "maxFailureWaitSeconds": 900,
+ "minimumQuickLoginWaitSeconds": 60,
+ "waitIncrementSeconds": 60,
+ "quickLoginCheckMilliSeconds": 1000,
+ "maxDeltaTimeSeconds": 43200,
+ "failureFactor": 30,
+ "roles": {
+ "realm": [
+ {
+ "id": "c1c757e3-1483-4a13-a650-57d13762063d",
+ "name": "offline_access",
+ "description": "${role_offline-access}",
+ "composite": false,
+ "clientRole": false,
+ "containerId": "a63b0d92-16b3-4110-8dd8-b25ed575035a",
+ "attributes": {}
+ },
+ {
+ "id": "1df44d36-8c3e-47a9-8b37-28b31c9c5fd1",
+ "name": "uma_authorization",
+ "description": "${role_uma_authorization}",
+ "composite": false,
+ "clientRole": false,
+ "containerId": "a63b0d92-16b3-4110-8dd8-b25ed575035a",
+ "attributes": {}
+ },
+ {
+ "id": "03ee0166-2480-429b-bc22-8f6fcd4f8126",
+ "name": "default-roles-REALM_NAME_PLACEHOLDER",
+ "description": "${role_default-roles}",
+ "composite": true,
+ "composites": {
+ "realm": [
+ "offline_access",
+ "uma_authorization"
+ ],
+ "client": {
+ "account": [
+ "view-profile",
+ "manage-account"
+ ]
+ }
+ },
+ "clientRole": false,
+ "containerId": "a63b0d92-16b3-4110-8dd8-b25ed575035a",
+ "attributes": {}
+ }
+ ],
+ "client": {
+ "realm-management": [
+ {
+ "id": "1305643f-47b2-471a-95b0-42f962443c0e",
+ "name": "view-authorization",
+ "description": "${role_view-authorization}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "deb716da-2b9c-429d-a23a-21e3e40caf11",
+ "name": "view-realm",
+ "description": "${role_view-realm}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "be59b49b-4a79-400f-a67b-0a17903155c9",
+ "name": "manage-realm",
+ "description": "${role_manage-realm}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "9b2e7245-5859-49fd-a3b0-aeb215dc6e12",
+ "name": "view-users",
+ "description": "${role_view-users}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "query-groups",
+ "query-users"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "7e010c9f-565b-450b-a222-0122ab71010d",
+ "name": "manage-clients",
+ "description": "${role_manage-clients}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "92004b3a-9187-4f73-9169-319dbdec02bb",
+ "name": "query-groups",
+ "description": "${role_query-groups}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "696b1e73-b5f0-4990-a00f-943a53ff4555",
+ "name": "manage-users",
+ "description": "${role_manage-users}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "aae4db77-9a27-4cb7-b6f6-3f109f553502",
+ "name": "query-users",
+ "description": "${role_query-users}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "e2fd690b-88be-4953-8bff-3225e40fdbd4",
+ "name": "view-events",
+ "description": "${role_view-events}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "39b3b817-bea6-47f5-8b34-4fc32211e433",
+ "name": "manage-authorization",
+ "description": "${role_manage-authorization}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "2615c6ce-7dc4-448b-940f-26905a99b25d",
+ "name": "manage-events",
+ "description": "${role_manage-events}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "254a5871-81e9-4e96-b6a1-cf6c27d3ddb2",
+ "name": "query-realms",
+ "description": "${role_query-realms}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "81582a5b-5be7-45be-9c0b-52582ede762a",
+ "name": "manage-identity-providers",
+ "description": "${role_manage-identity-providers}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "322ce24f-42f5-40c6-a8bd-d31734ac9834",
+ "name": "impersonation",
+ "description": "${role_impersonation}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "30e5d91d-ac17-4812-ba11-cba05e1add77",
+ "name": "realm-admin",
+ "description": "${role_realm-admin}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "view-authorization",
+ "view-realm",
+ "manage-realm",
+ "view-users",
+ "manage-clients",
+ "query-groups",
+ "manage-users",
+ "query-users",
+ "view-events",
+ "manage-authorization",
+ "query-realms",
+ "manage-events",
+ "manage-identity-providers",
+ "impersonation",
+ "view-clients",
+ "create-client",
+ "query-clients",
+ "view-identity-providers"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "c21b3f56-ea00-4e69-905d-88fdb6e78dfa",
+ "name": "create-client",
+ "description": "${role_create-client}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "93612d37-df0a-4898-9c9a-c01afb1249b8",
+ "name": "view-clients",
+ "description": "${role_view-clients}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "query-clients"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "1e59ed3e-a91c-4ee3-8b29-a8da6c035549",
+ "name": "query-clients",
+ "description": "${role_query-clients}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ },
+ {
+ "id": "15a8e4ef-f406-44e6-b4dc-21fdce6fd023",
+ "name": "view-identity-providers",
+ "description": "${role_view-identity-providers}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "attributes": {}
+ }
+ ],
+ "security-admin-console": [],
+ "admin-cli": [],
+ "account-console": [],
+ "broker": [
+ {
+ "id": "ed91f070-bce3-4b4c-a1bd-066bc96ff3e0",
+ "name": "read-token",
+ "description": "${role_read-token}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "db9b8810-7b16-47a9-8b9e-8de58449c206",
+ "attributes": {}
+ }
+ ],
+ "account": [
+ {
+ "id": "f583ff69-51dc-4c6e-8a1d-addf142c3220",
+ "name": "delete-account",
+ "description": "${role_delete-account}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "28e61d0d-c4dc-4a91-8012-1a2f0325945c",
+ "attributes": {}
+ },
+ {
+ "id": "9ac5bf5b-bb5d-4138-b397-04ea73622a60",
+ "name": "view-profile",
+ "description": "${role_view-profile}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "28e61d0d-c4dc-4a91-8012-1a2f0325945c",
+ "attributes": {}
+ },
+ {
+ "id": "ab3ce8f1-ec74-4a35-b00a-259db0bc0878",
+ "name": "view-consent",
+ "description": "${role_view-consent}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "28e61d0d-c4dc-4a91-8012-1a2f0325945c",
+ "attributes": {}
+ },
+ {
+ "id": "6907ab95-1c60-4f5b-912b-ee6d5c98346d",
+ "name": "manage-account",
+ "description": "${role_manage-account}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "account": [
+ "manage-account-links"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "28e61d0d-c4dc-4a91-8012-1a2f0325945c",
+ "attributes": {}
+ },
+ {
+ "id": "073dfba9-b2b5-42de-a147-e0ac00b9cd76",
+ "name": "view-groups",
+ "description": "${role_view-groups}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "28e61d0d-c4dc-4a91-8012-1a2f0325945c",
+ "attributes": {}
+ },
+ {
+ "id": "e9989640-ed85-40e5-86fc-51473fdafd4f",
+ "name": "view-applications",
+ "description": "${role_view-applications}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "28e61d0d-c4dc-4a91-8012-1a2f0325945c",
+ "attributes": {}
+ },
+ {
+ "id": "d5b8032e-e9b2-44fb-8354-ac3e068fb6d3",
+ "name": "manage-account-links",
+ "description": "${role_manage-account-links}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "28e61d0d-c4dc-4a91-8012-1a2f0325945c",
+ "attributes": {}
+ },
+ {
+ "id": "93560eab-3dd4-4ff4-b252-6f6c2103ff31",
+ "name": "manage-consent",
+ "description": "${role_manage-consent}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "account": [
+ "view-consent"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "28e61d0d-c4dc-4a91-8012-1a2f0325945c",
+ "attributes": {}
+ }
+ ]
+ }
+ },
+ "groups": [],
+ "defaultRole": {
+ "id": "03ee0166-2480-429b-bc22-8f6fcd4f8126",
+ "name": "default-roles-REALM_NAME_PLACEHOLDER",
+ "description": "${role_default-roles}",
+ "composite": true,
+ "clientRole": false,
+ "containerId": "a63b0d92-16b3-4110-8dd8-b25ed575035a"
+ },
+ "requiredCredentials": [
+ "password"
+ ],
+ "otpPolicyType": "totp",
+ "otpPolicyAlgorithm": "HmacSHA1",
+ "otpPolicyInitialCounter": 0,
+ "otpPolicyDigits": 6,
+ "otpPolicyLookAheadWindow": 1,
+ "otpPolicyPeriod": 30,
+ "otpPolicyCodeReusable": false,
+ "otpSupportedApplications": [
+ "totpAppGoogleName",
+ "totpAppFreeOTPName"
+ ],
+ "webAuthnPolicyRpEntityName": "keycloak",
+ "webAuthnPolicySignatureAlgorithms": [
+ "ES256"
+ ],
+ "webAuthnPolicyRpId": "",
+ "webAuthnPolicyAttestationConveyancePreference": "not specified",
+ "webAuthnPolicyAuthenticatorAttachment": "not specified",
+ "webAuthnPolicyRequireResidentKey": "not specified",
+ "webAuthnPolicyUserVerificationRequirement": "not specified",
+ "webAuthnPolicyCreateTimeout": 0,
+ "webAuthnPolicyAvoidSameAuthenticatorRegister": false,
+ "webAuthnPolicyAcceptableAaguids": [],
+ "webAuthnPolicyPasswordlessRpEntityName": "keycloak",
+ "webAuthnPolicyPasswordlessSignatureAlgorithms": [
+ "ES256"
+ ],
+ "webAuthnPolicyPasswordlessRpId": "",
+ "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
+ "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
+ "webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
+ "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
+ "webAuthnPolicyPasswordlessCreateTimeout": 0,
+ "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
+ "webAuthnPolicyPasswordlessAcceptableAaguids": [],
+ "scopeMappings": [
+ {
+ "clientScope": "offline_access",
+ "roles": [
+ "offline_access"
+ ]
+ }
+ ],
+ "clientScopeMappings": {
+ "account": [
+ {
+ "client": "account-console",
+ "roles": [
+ "manage-account",
+ "view-groups"
+ ]
+ }
+ ]
+ },
+ "clients": [
+ {
+ "id": "28e61d0d-c4dc-4a91-8012-1a2f0325945c",
+ "clientId": "account",
+ "name": "${client_account}",
+ "rootUrl": "${authBaseUrl}",
+ "baseUrl": "/realms/REALM_NAME_PLACEHOLDER/account/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/realms/REALM_NAME_PLACEHOLDER/account/*"
+ ],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "post.logout.redirect.uris": "+"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "a1797864-8592-4d75-b2c0-af15ca029abd",
+ "clientId": "account-console",
+ "name": "${client_account-console}",
+ "rootUrl": "${authBaseUrl}",
+ "baseUrl": "/realms/REALM_NAME_PLACEHOLDER/account/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/realms/REALM_NAME_PLACEHOLDER/account/*"
+ ],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "post.logout.redirect.uris": "+",
+ "pkce.code.challenge.method": "S256"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "protocolMappers": [
+ {
+ "id": "7e32f2c3-d9fb-40e0-a618-fb68c921f9d9",
+ "name": "audience resolve",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-resolve-mapper",
+ "consentRequired": false,
+ "config": {}
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "bb4d6126-c9c3-4c39-8016-805d04d55829",
+ "clientId": "admin-cli",
+ "name": "${client_admin-cli}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": false,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": true,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "db9b8810-7b16-47a9-8b9e-8de58449c206",
+ "clientId": "broker",
+ "name": "${client_broker}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": true,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "61f1ed79-6efa-4109-9051-cd26de56f538",
+ "clientId": "realm-management",
+ "name": "${client_realm-management}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": true,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "6c009e16-d012-43ac-9093-ce95786c2cb8",
+ "clientId": "security-admin-console",
+ "name": "${client_security-admin-console}",
+ "rootUrl": "${authAdminUrl}",
+ "baseUrl": "/admin/REALM_NAME_PLACEHOLDER/console/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/admin/REALM_NAME_PLACEHOLDER/console/*"
+ ],
+ "webOrigins": [
+ "+"
+ ],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "post.logout.redirect.uris": "+",
+ "pkce.code.challenge.method": "S256"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "protocolMappers": [
+ {
+ "id": "84f24df3-9b58-41fb-a05a-e591fc47e9d7",
+ "name": "locale",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "locale",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "locale",
+ "jsonType.label": "String"
+ }
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ }
+ ],
+ "clientScopes": [
+ {
+ "id": "aa08b21f-f33f-4079-be3d-1e925b44c935",
+ "name": "offline_access",
+ "description": "OpenID Connect built-in scope: offline_access",
+ "protocol": "openid-connect",
+ "attributes": {
+ "consent.screen.text": "${offlineAccessScopeConsentText}",
+ "display.on.consent.screen": "true"
+ }
+ },
+ {
+ "id": "ab4f2643-cc27-463e-bfba-44712cffb45e",
+ "name": "acr",
+ "description": "OpenID Connect scope for add acr (authentication context class reference) to the token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "false"
+ },
+ "protocolMappers": [
+ {
+ "id": "bcc3ec1d-d4bb-4171-82c3-e9b7f2de7371",
+ "name": "acr loa level",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-acr-mapper",
+ "consentRequired": false,
+ "config": {
+ "id.token.claim": "true",
+ "access.token.claim": "true"
+ }
+ }
+ ]
+ },
+ {
+ "id": "804093f4-8a08-4cca-a1a1-6008b7695e92",
+ "name": "web-origins",
+ "description": "OpenID Connect scope for add allowed web origins to the access token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "false",
+ "consent.screen.text": ""
+ },
+ "protocolMappers": [
+ {
+ "id": "17a68f02-d8dc-4771-aeeb-d6e262e4fd07",
+ "name": "allowed web origins",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-allowed-origins-mapper",
+ "consentRequired": false,
+ "config": {}
+ }
+ ]
+ },
+ {
+ "id": "bb39a86e-661c-47ef-aa54-d3d2da043340",
+ "name": "phone",
+ "description": "OpenID Connect built-in scope: phone",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${phoneScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "17d26261-10f5-4f60-8cf5-c4106af3a3ee",
+ "name": "phone number",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "phoneNumber",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "phone_number",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "4a18f46f-63ac-4577-89c1-caa895a05255",
+ "name": "phone number verified",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "phoneNumberVerified",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "phone_number_verified",
+ "jsonType.label": "boolean"
+ }
+ }
+ ]
+ },
+ {
+ "id": "c91c9396-3cca-48c7-93b8-e93567f56f7e",
+ "name": "profile",
+ "description": "OpenID Connect built-in scope: profile",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${profileScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "888660e1-577c-4249-9703-e86241b9e714",
+ "name": "birthdate",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "birthdate",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "birthdate",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "3ddfe32a-e127-4808-8f59-a7ba97345258",
+ "name": "locale",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "locale",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "locale",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "ab023b96-89e4-41ed-b923-288bac047809",
+ "name": "middle name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "middleName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "middle_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "010b1c53-3403-476c-904f-81f51eaf297a",
+ "name": "username",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "username",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "preferred_username",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "558d8acf-56c5-4011-a366-f4370ebfaa4c",
+ "name": "zoneinfo",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "zoneinfo",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "zoneinfo",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "5ca091f1-dd75-4f51-92cf-8fe52e1bd91a",
+ "name": "picture",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "picture",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "picture",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "c77ea1c7-af58-4fe4-8760-d5fc367a537d",
+ "name": "website",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "website",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "website",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "8aa68575-a903-46ae-adb7-43b4c5573f88",
+ "name": "nickname",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "nickname",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "nickname",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "319c76bc-93b5-4f78-b371-760f01143ffb",
+ "name": "profile",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "profile",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "profile",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "682141fe-c658-4a27-9c4f-d12cd6fd639d",
+ "name": "given name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "firstName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "given_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "31285f11-a0a0-4e95-a204-acda390961be",
+ "name": "gender",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "gender",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "gender",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "ee8c508a-f021-46c8-ba42-9f32b32aa504",
+ "name": "full name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-full-name-mapper",
+ "consentRequired": false,
+ "config": {
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "userinfo.token.claim": "true"
+ }
+ },
+ {
+ "id": "6aad901c-f1c7-46d8-bfc2-ddd17b37e73d",
+ "name": "family name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "lastName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "family_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "72f7e384-849a-475f-ad2d-0ea19319edd3",
+ "name": "updated at",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "updatedAt",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "updated_at",
+ "jsonType.label": "long"
+ }
+ }
+ ]
+ },
+ {
+ "id": "204b6707-5432-43d6-928f-ed17669edc8e",
+ "name": "email",
+ "description": "OpenID Connect built-in scope: email",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${emailScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "6ffca153-999d-45dc-a98c-37ad1f79b04e",
+ "name": "email",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "email",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "email",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "c8e75ea4-0006-4f7c-882c-8f1499bf14ca",
+ "name": "email verified",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "emailVerified",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "email_verified",
+ "jsonType.label": "boolean"
+ }
+ }
+ ]
+ },
+ {
+ "id": "24c8b752-95fa-4b11-9c99-1da3d7028783",
+ "name": "address",
+ "description": "OpenID Connect built-in scope: address",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${addressScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "07b45364-f53c-453f-9d6f-1122586e8633",
+ "name": "address",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-address-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute.formatted": "formatted",
+ "user.attribute.country": "country",
+ "user.attribute.postal_code": "postal_code",
+ "userinfo.token.claim": "true",
+ "user.attribute.street": "street",
+ "id.token.claim": "true",
+ "user.attribute.region": "region",
+ "access.token.claim": "true",
+ "user.attribute.locality": "locality"
+ }
+ }
+ ]
+ },
+ {
+ "id": "e0c34249-b2e2-49cf-b414-9aac15acd82b",
+ "name": "microprofile-jwt",
+ "description": "Microprofile - JWT built-in scope",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "false"
+ },
+ "protocolMappers": [
+ {
+ "id": "fcf43c71-170f-4c04-90b5-d6aefb16c7a5",
+ "name": "upn",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "username",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "upn",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "88097d77-681a-4b3a-a025-92fae6182a15",
+ "name": "groups",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-realm-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "multivalued": "true",
+ "user.attribute": "foo",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "groups",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "ac7c6a5d-9d21-4712-889f-951ba412ced0",
+ "name": "role_list",
+ "description": "SAML role list",
+ "protocol": "saml",
+ "attributes": {
+ "consent.screen.text": "${samlRoleListScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "9f08ee07-98a9-496d-b90c-897b38bd2dd3",
+ "name": "role list",
+ "protocol": "saml",
+ "protocolMapper": "saml-role-list-mapper",
+ "consentRequired": false,
+ "config": {
+ "single": "false",
+ "attribute.nameformat": "Basic",
+ "attribute.name": "Role"
+ }
+ }
+ ]
+ },
+ {
+ "id": "6ba80bef-0a4f-4be1-9e34-89f1a9c8c976",
+ "name": "roles",
+ "description": "OpenID Connect scope for add user roles to the access token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${rolesScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "9e774de8-10f9-4c1f-b70e-242f07532cf7",
+ "name": "realm roles",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-realm-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "foo",
+ "access.token.claim": "true",
+ "claim.name": "realm_access.roles",
+ "jsonType.label": "String",
+ "multivalued": "true"
+ }
+ },
+ {
+ "id": "2086dce7-3707-4101-9174-7ca97082d228",
+ "name": "audience resolve",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-resolve-mapper",
+ "consentRequired": false,
+ "config": {}
+ },
+ {
+ "id": "7da3ae82-c74d-456e-a1f4-23f5d2ad6919",
+ "name": "client roles",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-client-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "foo",
+ "access.token.claim": "true",
+ "claim.name": "resource_access.${client_id}.roles",
+ "jsonType.label": "String",
+ "multivalued": "true"
+ }
+ }
+ ]
+ }
+ ],
+ "defaultDefaultClientScopes": [
+ "role_list",
+ "profile",
+ "email",
+ "roles",
+ "web-origins",
+ "acr"
+ ],
+ "defaultOptionalClientScopes": [
+ "offline_access",
+ "address",
+ "phone",
+ "microprofile-jwt"
+ ],
+ "browserSecurityHeaders": {
+ "contentSecurityPolicyReportOnly": "",
+ "xContentTypeOptions": "nosniff",
+ "xRobotsTag": "none",
+ "xFrameOptions": "SAMEORIGIN",
+ "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+ "xXSSProtection": "1; mode=block",
+ "strictTransportSecurity": "max-age=31536000; includeSubDomains"
+ },
+ "smtpServer": {},
+ "eventsEnabled": false,
+ "eventsListeners": [
+ "jboss-logging"
+ ],
+ "enabledEventTypes": [],
+ "adminEventsEnabled": false,
+ "adminEventsDetailsEnabled": false,
+ "identityProviders": [],
+ "identityProviderMappers": [],
+ "components": {
+ "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [
+ {
+ "id": "fc6af199-36bb-4721-8805-65b15ac23677",
+ "name": "Full Scope Disabled",
+ "providerId": "scope",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {}
+ },
+ {
+ "id": "4eca2c9d-3fd9-4798-a96f-66ab020f0999",
+ "name": "Allowed Client Scopes",
+ "providerId": "allowed-client-templates",
+ "subType": "authenticated",
+ "subComponents": {},
+ "config": {
+ "allow-default-scopes": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "a6493944-7b42-47c9-8161-15bcce5e1dea",
+ "name": "Allowed Protocol Mapper Types",
+ "providerId": "allowed-protocol-mappers",
+ "subType": "authenticated",
+ "subComponents": {},
+ "config": {
+ "allowed-protocol-mapper-types": [
+ "saml-user-attribute-mapper",
+ "oidc-full-name-mapper",
+ "saml-user-property-mapper",
+ "oidc-sha256-pairwise-sub-mapper",
+ "oidc-usermodel-property-mapper",
+ "oidc-usermodel-attribute-mapper",
+ "oidc-address-mapper",
+ "saml-role-list-mapper"
+ ]
+ }
+ },
+ {
+ "id": "20f18ede-0082-4211-8193-97b3faf58832",
+ "name": "Trusted Hosts",
+ "providerId": "trusted-hosts",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "host-sending-registration-request-must-match": [
+ "true"
+ ],
+ "client-uris-must-match": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "59fd957f-035a-4381-ba69-b07befc54769",
+ "name": "Allowed Protocol Mapper Types",
+ "providerId": "allowed-protocol-mappers",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "allowed-protocol-mapper-types": [
+ "saml-user-attribute-mapper",
+ "oidc-usermodel-attribute-mapper",
+ "oidc-full-name-mapper",
+ "oidc-sha256-pairwise-sub-mapper",
+ "oidc-address-mapper",
+ "saml-role-list-mapper",
+ "saml-user-property-mapper",
+ "oidc-usermodel-property-mapper"
+ ]
+ }
+ },
+ {
+ "id": "b5cf58aa-ebfe-4da0-adcf-ad3faee18502",
+ "name": "Allowed Client Scopes",
+ "providerId": "allowed-client-templates",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "allow-default-scopes": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "acec3143-8444-4d8f-9020-5fdd1992bfa8",
+ "name": "Consent Required",
+ "providerId": "consent-required",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {}
+ },
+ {
+ "id": "6555ff94-661a-4659-9cde-0eb2147892ea",
+ "name": "Max Clients Limit",
+ "providerId": "max-clients",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "max-clients": [
+ "200"
+ ]
+ }
+ }
+ ],
+ "org.keycloak.keys.KeyProvider": [
+ {
+ "id": "f957405f-8f50-432a-8ade-8805d27e8b04",
+ "name": "rsa-generated",
+ "providerId": "rsa-generated",
+ "subComponents": {},
+ "config": {
+ "privateKey": [
+ "MIIEpAIBAAKCAQEA68PJqiC6cMTIaFvxsnhkyHXiOuwMxa3Udvu3lYJggl+3hMK9Pn1x7ojApUEch53qCIDLJADmr93aofdylZlLLdK/8vDViq8XWnodDfVDi6FttLhGhWiO7e37KswQ2wbosbQFbWIdU8brbsH1sm7snkwGTUuTXt3RDmWOlamomlbeumxNo9SaG+SSMdqwzB1KAu6IQwARvbA8LvzfMhlc6jh16o7CO1QTNFlbZ/8RDmu0T/pOF9TUccsw0hPiFbGzVy7+lANEVFXY9Un0sZTtb3xhJ6l9zsn07ZZEZ6D4COY0yGROWD5bvNUusZvDuzkg75myEHNDb4iZY0+DaiVRwQIDAQABAoIBABaWcUWOPCkzWTtSWm4tsFjaSRyPDUw1HW7G1VhgH4HuIgV4qNaKAIveEzg3QZX7+vY/QfccP6hoGhsRZit5/noQlRj1ROg0DTSQZXnhs8vMDALX8tMI6O9XsQwbyp5JY6rUI1RO+vNR/Vq6VMv4ak1iMupd4WvMgaEeTrz8/lfG6BxBcCGx8Wpvxsd9VvcAyPqXwI2C5y0JSnOJIHRxvLr2NmQeFdFppcVlucQV1SCzxnbMRcI5i0RKuOo/9yJJForwFJcFzkAxWgeUnJglNw/C/20s0aKwM+z+mBAFK/uZPjvEVcbTXj3KM1iuWs5l6FW03YyI5xO5EC2fRUmUKWcCgYEA+Yx2t6GSQ6YJ/v4DhaZv2rzEtn5G9Nk4J98w2GiQAjW4SBRp+vaWrmWhvkvrpX6lp741k9jK6CViayEE05orEHmVjHM885AiddQc88zxtCpGijMR1FuVdklswd0LnyB/PLWgr3f7Z1qAYyFCbxnpcg76jpQCpo36h40KEOO80BcCgYEA8dwZ1/Vwq6UDJBvM9QBvjOnW7Jeoico2m2Hsd74v9G1si+yywyvIMphVnlqoHsXqdxi79ZHJXiyfB/zmQWO9dEhcxq2OubaemDzeJLwXRcLW+Cg4VNIirDdZEWo/nhD7P+00IP/y8Z5neguWYVc01sLkCGB46z8Q/8R59xuZ++cCgYEA0/F9framD/h8MuqwORnDlEaQ1+HmB9xZOlvwE0yzSn0vl2BnJnO6REIjHglDCVrH/PCqdnhA1OuzbAMuIz2j56kr346cLMy0x9gwAsyEWB0zrfpz4SUrirwPt5MyZKLoDbrAz2aaygvuUMMVtmCOiYW5PdDtc2HQbsHV08RoP18CgYB09fi1fCcxioobUypprP1FCux529mQUO7Zc6CUQ7ATJzuf6yaDxc950DtPag31W8bIM3jqB8d2uGNrzHxZUO+UpU3gcpwb6VmGy6Ct6RvkC5ZDycd8FWbZG6cCCfyb5yBpyL812jDVccIevi3KAw81cGgwON8g/I2u8of83Sc5LwKBgQCtVDV1OHE24Y2DxRAakZ5fMp3NYIE8Y+5XrhwHdWRa72AaAz7DrU12b7yZJH5y/upV4Gv12Ia1o1pAx9mXSnVb0WSHp1A8UNtCVlivtnr66BGb5X5ucw53Wz+ciL3KgoHm5pU7Q/6UxttWyikvF2uBp6xMBWOcv3b1f6erxcw2aQ=="
+ ],
+ "keyUse": [
+ "SIG"
+ ],
+ "certificate": [
+ "MIICoTCCAYkCBgGGVKQ/mjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlkZW1vcmVhbG0wHhcNMjMwMjE1MTAzMzE1WhcNMzMwMjE1MTAzNDU1WjAUMRIwEAYDVQQDDAlkZW1vcmVhbG0wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDrw8mqILpwxMhoW/GyeGTIdeI67AzFrdR2+7eVgmCCX7eEwr0+fXHuiMClQRyHneoIgMskAOav3dqh93KVmUst0r/y8NWKrxdaeh0N9UOLoW20uEaFaI7t7fsqzBDbBuixtAVtYh1TxutuwfWybuyeTAZNS5Ne3dEOZY6VqaiaVt66bE2j1Job5JIx2rDMHUoC7ohDABG9sDwu/N8yGVzqOHXqjsI7VBM0WVtn/xEOa7RP+k4X1NRxyzDSE+IVsbNXLv6UA0RUVdj1SfSxlO1vfGEnqX3OyfTtlkRnoPgI5jTIZE5YPlu81S6xm8O7OSDvmbIQc0NviJljT4NqJVHBAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHTSxIteVa2a1V4pqCHweJTRxoXOGE6048ZtEzOsO/5xElynszVZ1iMXlRq8uNTlc80Icx4hw17attP7KCColFIwZ0HCq1IfLQEquoHBaLDhIhVQ7ehCTkto/u8nLgfZL+NDkO+nT+i5eNctMQG74x6hTV3Urc5z4MnBtJNqtPvR+Lw0pbtH07f+K345Z06nxES0Hnb6TLsw8BuTTKPfSqVIAbsi4n3pUgULdeVRd0iYaSQdmwRaFEntWzUJlM4GjvaIPkaMS1CwjEBuutLzskVSiFlQ26W8KwXn7ySIBlec4ox3VD+Q7YynR64bB6Hs1MmFFuooTjn4c02uytLmK2o="
+ ],
+ "priority": [
+ "100"
+ ]
+ }
+ },
+ {
+ "id": "d0d08daf-ba76-4e82-8183-37aa8f9a6af1",
+ "name": "rsa-enc-generated",
+ "providerId": "rsa-enc-generated",
+ "subComponents": {},
+ "config": {
+ "privateKey": [
+ "MIIEpAIBAAKCAQEA6wG/F8mo6eXBXSuShH9D2ybnMNUfh9dbRJ+Bporl/XNOSxBKaiyo+2W1VIdrjsedwmQuQoFjs2f229qzBS9Fl4ChLxlIjJEW1U+bPilRZUDlSM3q2HE6O4acP+nSIG8ZW9/KhXPgcanM+MixkM9cHzO7bqGKKcnCKD5Y8ia2Vc1PXPNguxmDwuj9XSlpdDOzRZiMUZzcqxzxWgyfUTD839NN16AM6tN4CBIuK779Zwah0ym4wLiVdX2UCJNVzVzuo16YoXYOlXC+skiWG+M4pjj3/IKkLQvzpO9Zh1x6NNMsstGQhPSRUq4KX4fquQVDwxDvIzsIWn2pcTmkOsdWSwIDAQABAoIBADCrTWx7PoimJOwLPI5FHwPxZBrIYH3M+2FUWVDo3iWlrha8mnSvqBVcZHfLjdple8YI4k2ypze99bFlcwLFXfe402jCJzS5TY3CrUdr3igGjxWLU7IcjO9L+ur/nR1LdOiCidome9p+TG1Pfvqa/xyVJaGNQeRSnOuhseEAZG2TMEidK0nWI1NQdm5Q6hsNI2UcPbq3+0ouHz2xBYGoKln76Ibqk5yfNty60jtxeQwg1P0I5PjiyLIiOQUKzaGEX6NENr/WI0qXLr5460ioCqI3Urrgml+lDij/Tg5BXs/Dd1awbup3/vUId/gd7Hy99tXDOK0iXyjZThfgBhsBiYUCgYEA/5zJhrn3g3YyFhPljP4xQBP3k4f/sPBihNwshsa/P8DBIFvxBE3jL+u8QZ/d1PU935gq4183HT8Nk7DFoQ0pntdLyJxfZ5oF07d0qYoHY++R5OIqX2VK2AXBGbwuCUct/XXjEUn83MSBgg1GGbY6qyty1UwBqQhN+qqiOxcUfS0CgYEA61z2IBNOs0T+ns4SsLZERM7uu2mV0IokaLQ60Rbk+7+sV+Mx0eapp4rXuxE33YFRrsvHonyfvbNZtqBnyw7fU8PQm5ozl9T1jeUAdgqm8l5cqpYswASL/NkWLkK3+D+ynLLjKygDZqMj3ZMO8c7nYw799QQaw4T9pzpJZjJLfFcCgYEArOk11kKEsdRJy2+IMBlf3ZXkO1ObXukt6+w43q8hfpH40tf/MUcy8R7JiacIW9/ODCwWjxrA4LLfj1HcTrblucKwTDOjwiSJ3o9ShsGNgEf2bFumCEQwHfO+jZcjmTkiXjvZ778aI4l2hjBOhGQmSdYpZyp0URECFxhIiCpzvL0CgYAYrtodCQlS4aR2URRCtgq40J7Wxr7wbNxeorAcZ3NCN5rCaNA7vB4EtRnkw2yBbWN8mmBoWPuDsIBzF6Vq9TdUmI+TEfvhK3NJG0AOIRXbCyxas38j8BYiQT4DQfn7Ler0ZgpO51Zb+DX1sct6boFzsQnPHUwVPyg+1m0GK7Yg5wKBgQDCIYvL6JhJidgP9ve3U0d0NUDAndRE5fuGqMcKvBiiRAE2D8RxHIWDre/NzrSLAst4UzmuPLG1LB1mIIfUHoPlHX5yEHbBRWtKeJUZ8tEU2z6uNZxP+ntf/K8fdkBS0jbowfG2G/nqqlyJuIrQduNvtT6aoZK0UjRtZ7iAdMjs5Q=="
+ ],
+ "keyUse": [
+ "ENC"
+ ],
+ "certificate": [
+ "MIICoTCCAYkCBgGGVKRAEDANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlkZW1vcmVhbG0wHhcNMjMwMjE1MTAzMzE1WhcNMzMwMjE1MTAzNDU1WjAUMRIwEAYDVQQDDAlkZW1vcmVhbG0wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDrAb8Xyajp5cFdK5KEf0PbJucw1R+H11tEn4GmiuX9c05LEEpqLKj7ZbVUh2uOx53CZC5CgWOzZ/bb2rMFL0WXgKEvGUiMkRbVT5s+KVFlQOVIzerYcTo7hpw/6dIgbxlb38qFc+Bxqcz4yLGQz1wfM7tuoYopycIoPljyJrZVzU9c82C7GYPC6P1dKWl0M7NFmIxRnNyrHPFaDJ9RMPzf003XoAzq03gIEi4rvv1nBqHTKbjAuJV1fZQIk1XNXO6jXpihdg6VcL6ySJYb4zimOPf8gqQtC/Ok71mHXHo00yyy0ZCE9JFSrgpfh+q5BUPDEO8jOwhafalxOaQ6x1ZLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEkOE5zWi8x3NfPWsdZkLckRw9vQFDYhQuaRZfD1i3lKvYW9xERFjOICuSHUX9yxX/CpGWVDAomXXXYxvlPpkENO/GjUGcL5UH6AopPkOzUZwsVWEylR6nczlK9sXjfjqgDOFwV19q5bn6hiV6qLG4Ty747lCATaxCUDPwJvZE8ZLFTHrccFtAH8VXCZbJJMLXO42LgMeG5nF4Tf1K0iI+4sSDWshl+QNugmaRQSrG0IklH4+U9J9JTwAiibkspgVsc2ubhbA+Xvzndg0vIQ2cEVWLqK9tRAIuaoANTmJneBZdBoVL5gtY3jCyXj6ecrKr+4JzeXCwmrxQUk9061eDU="
+ ],
+ "priority": [
+ "100"
+ ],
+ "algorithm": [
+ "RSA-OAEP"
+ ]
+ }
+ },
+ {
+ "id": "0d0237f6-29a9-4e1d-8de0-0490ab1c9118",
+ "name": "hmac-generated",
+ "providerId": "hmac-generated",
+ "subComponents": {},
+ "config": {
+ "kid": [
+ "1523f166-af8b-4970-94ff-eabb0f391532"
+ ],
+ "secret": [
+ "ByJpObMtnXpqZwygKnj_cgP-SkhVJPH_D-vgOS8yRSH9Km9idi4Ryh5w__zKGk4OeIJWQWRSz5VG_6kzINchKw"
+ ],
+ "priority": [
+ "100"
+ ],
+ "algorithm": [
+ "HS256"
+ ]
+ }
+ },
+ {
+ "id": "53a26567-105e-4b11-bbd1-1516fe76104a",
+ "name": "aes-generated",
+ "providerId": "aes-generated",
+ "subComponents": {},
+ "config": {
+ "kid": [
+ "8d1e845c-f3bc-4b6c-86c5-acbc49442386"
+ ],
+ "secret": [
+ "EWEleDkIM15zP8tyIr6nHw"
+ ],
+ "priority": [
+ "100"
+ ]
+ }
+ }
+ ]
+ },
+ "internationalizationEnabled": false,
+ "supportedLocales": [],
+ "authenticationFlows": [
+ {
+ "id": "c3820085-85d3-4ff8-bd42-15464fa668b6",
+ "alias": "Account verification options",
+ "description": "Method with which to verity the existing account",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-email-verification",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Verify Existing Account by Re-authentication",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "815709b3-7421-44b3-bf18-4838cf354852",
+ "alias": "Authentication Options",
+ "description": "Authentication options.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "basic-auth",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "basic-auth-otp",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-spnego",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 30,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "6b97ee19-cc94-435d-92cd-c16cec1ce04e",
+ "alias": "Browser - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-otp-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "8ce4d49e-4ef9-4f99-ab46-3693b7b4a093",
+ "alias": "Direct Grant - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "direct-grant-validate-otp",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "2d7a3dd7-cfa2-427c-b1c6-aa91a4cd6c63",
+ "alias": "First broker login - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-otp-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "bf73abb4-36f2-4338-8578-86ab06bb1131",
+ "alias": "Handle Existing Account",
+ "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-confirm-link",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Account verification options",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "65caf860-42ee-4bbe-aafe-468c838cf602",
+ "alias": "Reset - Conditional OTP",
+ "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "reset-otp",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "bf7960c0-0247-442b-b381-bea5646a4912",
+ "alias": "User creation or linking",
+ "description": "Flow for the existing/non-existing user alternatives",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticatorConfig": "create unique user config",
+ "authenticator": "idp-create-user-if-unique",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Handle Existing Account",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "1f2b94c0-0f10-4484-a224-0699141f7c02",
+ "alias": "Verify Existing Account by Re-authentication",
+ "description": "Reauthentication of existing account",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-username-password-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "First broker login - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "a34173a7-4ad7-4817-ad11-9ddc459854aa",
+ "alias": "browser",
+ "description": "browser based authentication",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "auth-cookie",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-spnego",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "identity-provider-redirector",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 25,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 30,
+ "autheticatorFlow": true,
+ "flowAlias": "forms",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "a69e205f-6ae1-4aa1-9ed1-806dbc5f7168",
+ "alias": "clients",
+ "description": "Base authentication for clients",
+ "providerId": "client-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "client-secret",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "client-jwt",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "client-secret-jwt",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 30,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "client-x509",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 40,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "18b4d1ed-9fcd-41b2-8db0-cdc74d9ad155",
+ "alias": "direct grant",
+ "description": "OpenID Connect Resource Owner Grant",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "direct-grant-validate-username",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "direct-grant-validate-password",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 30,
+ "autheticatorFlow": true,
+ "flowAlias": "Direct Grant - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "7aeeddfa-01fa-43c2-80ad-3d7089b8d952",
+ "alias": "docker auth",
+ "description": "Used by Docker clients to authenticate against the IDP",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "docker-http-basic-authenticator",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "4e0d5e38-0c28-4ad3-b904-e1dcde038e7f",
+ "alias": "first broker login",
+ "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticatorConfig": "review profile config",
+ "authenticator": "idp-review-profile",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "User creation or linking",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "c14d77a8-4c9f-429d-9d75-fd5d5046e140",
+ "alias": "forms",
+ "description": "Username, password, otp and other auth forms.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "auth-username-password-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Browser - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "e58d48bb-d404-40d9-9cfb-5fa5d450fef1",
+ "alias": "http challenge",
+ "description": "An authentication flow based on challenge-response HTTP Authentication Schemes",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "no-cookie-redirect",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Authentication Options",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "287e7e9a-1b9a-40b8-9d96-2718f336c12a",
+ "alias": "registration",
+ "description": "registration flow",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "registration-page-form",
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": true,
+ "flowAlias": "registration form",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "bad61d64-c8fb-4dad-b8fe-ce25da2de253",
+ "alias": "registration form",
+ "description": "registration form",
+ "providerId": "form-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "registration-user-creation",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "registration-profile-action",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 40,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "registration-password-action",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 50,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "registration-recaptcha-action",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 60,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "68449dd8-7be7-4150-82fe-fb75b67c896e",
+ "alias": "reset credentials",
+ "description": "Reset credentials for a user if they forgot their password or something",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "reset-credentials-choose-user",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "reset-credential-email",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "reset-password",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 30,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 40,
+ "autheticatorFlow": true,
+ "flowAlias": "Reset - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "baded0d1-49db-4723-8924-19f1c6e4b0d3",
+ "alias": "saml ecp",
+ "description": "SAML ECP Profile Authentication Flow",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "http-basic-authenticator",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ }
+ ],
+ "authenticatorConfig": [
+ {
+ "id": "c8e1e585-b8bb-417c-943d-079afbae72c5",
+ "alias": "create unique user config",
+ "config": {
+ "require.password.update.after.registration": "false"
+ }
+ },
+ {
+ "id": "07e5d37a-e1ed-4957-9802-f02b8565c715",
+ "alias": "review profile config",
+ "config": {
+ "update.profile.on.first.login": "missing"
+ }
+ }
+ ],
+ "requiredActions": [
+ {
+ "alias": "CONFIGURE_TOTP",
+ "name": "Configure OTP",
+ "providerId": "CONFIGURE_TOTP",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 10,
+ "config": {}
+ },
+ {
+ "alias": "terms_and_conditions",
+ "name": "Terms and Conditions",
+ "providerId": "terms_and_conditions",
+ "enabled": false,
+ "defaultAction": false,
+ "priority": 20,
+ "config": {}
+ },
+ {
+ "alias": "UPDATE_PASSWORD",
+ "name": "Update Password",
+ "providerId": "UPDATE_PASSWORD",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 30,
+ "config": {}
+ },
+ {
+ "alias": "UPDATE_PROFILE",
+ "name": "Update Profile",
+ "providerId": "UPDATE_PROFILE",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 40,
+ "config": {}
+ },
+ {
+ "alias": "VERIFY_EMAIL",
+ "name": "Verify Email",
+ "providerId": "VERIFY_EMAIL",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 50,
+ "config": {}
+ },
+ {
+ "alias": "delete_account",
+ "name": "Delete Account",
+ "providerId": "delete_account",
+ "enabled": false,
+ "defaultAction": false,
+ "priority": 60,
+ "config": {}
+ },
+ {
+ "alias": "webauthn-register",
+ "name": "Webauthn Register",
+ "providerId": "webauthn-register",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 70,
+ "config": {}
+ },
+ {
+ "alias": "webauthn-register-passwordless",
+ "name": "Webauthn Register Passwordless",
+ "providerId": "webauthn-register-passwordless",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 80,
+ "config": {}
+ },
+ {
+ "alias": "update_user_locale",
+ "name": "Update User Locale",
+ "providerId": "update_user_locale",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 1000,
+ "config": {}
+ }
+ ],
+ "browserFlow": "browser",
+ "registrationFlow": "registration",
+ "directGrantFlow": "direct grant",
+ "resetCredentialsFlow": "reset credentials",
+ "clientAuthenticationFlow": "clients",
+ "dockerAuthenticationFlow": "docker auth",
+ "attributes": {
+ "cibaBackchannelTokenDeliveryMode": "poll",
+ "cibaExpiresIn": "120",
+ "cibaAuthRequestedUserHint": "login_hint",
+ "oauth2DeviceCodeLifespan": "600",
+ "oauth2DevicePollingInterval": "5",
+ "parRequestUriLifespan": "60",
+ "cibaInterval": "5",
+ "realmReusableOtpCode": "false"
+ },
+ "keycloakVersion": "20.0.3",
+ "userManagedAccessAllowed": false,
+ "clientProfiles": {
+ "profiles": []
+ },
+ "clientPolicies": {
+ "policies": []
+ }
+}
diff --git a/src/main/resources/baseline/25.0.5/client/client.json b/src/main/resources/baseline/25.0.5/client/client.json
new file mode 100644
index 000000000..b96b479b1
--- /dev/null
+++ b/src/main/resources/baseline/25.0.5/client/client.json
@@ -0,0 +1,59 @@
+{
+ "clientId": "reference-client",
+ "name": "",
+ "description": "",
+ "rootUrl": "",
+ "adminUrl": "",
+ "baseUrl": "",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "cjQ7lt37eAxeBRDzmLDsML89l1F6MHeY",
+ "redirectUris": [
+ "/*"
+ ],
+ "webOrigins": [
+ "/*"
+ ],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": true,
+ "protocol": "openid-connect",
+ "attributes": {
+ "oidc.ciba.grant.enabled": "false",
+ "client.secret.creation.time": "1726783534",
+ "backchannel.logout.session.required": "true",
+ "oauth2.device.authorization.grant.enabled": "false",
+ "backchannel.logout.revoke.offline.tokens": "false"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": true,
+ "nodeReRegistrationTimeout": -1,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "roles",
+ "profile",
+ "basic",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "organization",
+ "microprofile-jwt"
+ ],
+ "access": {
+ "view": true,
+ "configure": true,
+ "manage": true
+ }
+}
diff --git a/src/main/resources/baseline/25.0.5/realm/realm.json b/src/main/resources/baseline/25.0.5/realm/realm.json
new file mode 100644
index 000000000..463be743b
--- /dev/null
+++ b/src/main/resources/baseline/25.0.5/realm/realm.json
@@ -0,0 +1,2355 @@
+{
+ "id": "dd63c101-0933-44ff-bd0d-6291b7b195ae",
+ "realm": "REALM_NAME_PLACEHOLDER",
+ "notBefore": 0,
+ "defaultSignatureAlgorithm": "RS256",
+ "revokeRefreshToken": false,
+ "refreshTokenMaxReuse": 0,
+ "accessTokenLifespan": 300,
+ "accessTokenLifespanForImplicitFlow": 900,
+ "ssoSessionIdleTimeout": 1800,
+ "ssoSessionMaxLifespan": 36000,
+ "ssoSessionIdleTimeoutRememberMe": 0,
+ "ssoSessionMaxLifespanRememberMe": 0,
+ "offlineSessionIdleTimeout": 2592000,
+ "offlineSessionMaxLifespanEnabled": false,
+ "offlineSessionMaxLifespan": 5184000,
+ "clientSessionIdleTimeout": 0,
+ "clientSessionMaxLifespan": 0,
+ "clientOfflineSessionIdleTimeout": 0,
+ "clientOfflineSessionMaxLifespan": 0,
+ "accessCodeLifespan": 60,
+ "accessCodeLifespanUserAction": 300,
+ "accessCodeLifespanLogin": 1800,
+ "actionTokenGeneratedByAdminLifespan": 43200,
+ "actionTokenGeneratedByUserLifespan": 300,
+ "oauth2DeviceCodeLifespan": 600,
+ "oauth2DevicePollingInterval": 5,
+ "enabled": true,
+ "sslRequired": "external",
+ "registrationAllowed": false,
+ "registrationEmailAsUsername": false,
+ "rememberMe": false,
+ "verifyEmail": false,
+ "loginWithEmailAllowed": true,
+ "duplicateEmailsAllowed": false,
+ "resetPasswordAllowed": false,
+ "editUsernameAllowed": false,
+ "bruteForceProtected": false,
+ "permanentLockout": false,
+ "maxTemporaryLockouts": 0,
+ "maxFailureWaitSeconds": 900,
+ "minimumQuickLoginWaitSeconds": 60,
+ "waitIncrementSeconds": 60,
+ "quickLoginCheckMilliSeconds": 1000,
+ "maxDeltaTimeSeconds": 43200,
+ "failureFactor": 30,
+ "roles": {
+ "realm": [
+ {
+ "id": "9580c9da-0c78-43c6-82b6-f1694db9bfa2",
+ "name": "uma_authorization",
+ "description": "${role_uma_authorization}",
+ "composite": false,
+ "clientRole": false,
+ "containerId": "dd63c101-0933-44ff-bd0d-6291b7b195ae",
+ "attributes": {}
+ },
+ {
+ "id": "480c5735-3615-4031-8af5-1a5941f6ed85",
+ "name": "default-roles-REALM_NAME_PLACEHOLDER",
+ "description": "${role_default-roles}",
+ "composite": true,
+ "composites": {
+ "realm": [
+ "offline_access",
+ "uma_authorization"
+ ],
+ "client": {
+ "account": [
+ "manage-account",
+ "view-profile"
+ ]
+ }
+ },
+ "clientRole": false,
+ "containerId": "dd63c101-0933-44ff-bd0d-6291b7b195ae",
+ "attributes": {}
+ },
+ {
+ "id": "acdaa4dc-3b37-4ef8-bc96-61d0bad24273",
+ "name": "offline_access",
+ "description": "${role_offline-access}",
+ "composite": false,
+ "clientRole": false,
+ "containerId": "dd63c101-0933-44ff-bd0d-6291b7b195ae",
+ "attributes": {}
+ }
+ ],
+ "client": {
+ "realm-management": [
+ {
+ "id": "cfb49ecc-087c-45ee-82b9-c04f09598ce7",
+ "name": "manage-users",
+ "description": "${role_manage-users}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "6fa23d54-426d-43fe-8fe9-1ea3eb901101",
+ "name": "view-authorization",
+ "description": "${role_view-authorization}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "98f722da-2e2b-4607-9cee-cfbf53593f36",
+ "name": "impersonation",
+ "description": "${role_impersonation}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "831f2cef-957c-4eaf-a309-e04ba25aed17",
+ "name": "view-clients",
+ "description": "${role_view-clients}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "query-clients"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "ad3da993-2344-45ab-adda-805025fe1c0e",
+ "name": "create-client",
+ "description": "${role_create-client}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "9144db3e-b609-4afa-a7fb-86340e7c4943",
+ "name": "manage-events",
+ "description": "${role_manage-events}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "64ce3225-b08c-45ac-b4da-a0f78ff53054",
+ "name": "query-clients",
+ "description": "${role_query-clients}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "bff7eea4-ef17-4873-8712-8461ac4a3ecb",
+ "name": "query-groups",
+ "description": "${role_query-groups}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "a8a226e0-fbdc-4a67-b4d8-53a945fad25c",
+ "name": "query-realms",
+ "description": "${role_query-realms}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "b22b71b1-a8dd-4aad-a879-a266a27f5da0",
+ "name": "realm-admin",
+ "description": "${role_realm-admin}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "manage-users",
+ "view-authorization",
+ "view-clients",
+ "impersonation",
+ "create-client",
+ "manage-events",
+ "query-clients",
+ "query-groups",
+ "query-realms",
+ "view-users",
+ "view-events",
+ "manage-clients",
+ "manage-identity-providers",
+ "manage-realm",
+ "query-users",
+ "view-identity-providers",
+ "manage-authorization",
+ "view-realm"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "56940251-b312-4ba5-8897-80770420fbc5",
+ "name": "view-users",
+ "description": "${role_view-users}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "query-users",
+ "query-groups"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "8080db13-00bd-4091-a36d-eb9a727c6e06",
+ "name": "manage-clients",
+ "description": "${role_manage-clients}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "c637da23-2962-43fd-ad60-3d722b83c991",
+ "name": "manage-identity-providers",
+ "description": "${role_manage-identity-providers}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "77347d4e-c2ba-4590-b9d7-2f6caacfb9c2",
+ "name": "view-events",
+ "description": "${role_view-events}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "eee3badf-8cfd-45e0-95e2-b31c4246b2ff",
+ "name": "manage-realm",
+ "description": "${role_manage-realm}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "62028465-2dbc-438c-a3da-d1028fc064cb",
+ "name": "query-users",
+ "description": "${role_query-users}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "c3d108ea-11e7-4c03-9e22-165e27a37b29",
+ "name": "view-identity-providers",
+ "description": "${role_view-identity-providers}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "f104fd30-19bc-41f1-8d1d-8ac8060f4d3e",
+ "name": "manage-authorization",
+ "description": "${role_manage-authorization}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ },
+ {
+ "id": "291747a2-0c07-4265-afe8-08a195e6d029",
+ "name": "view-realm",
+ "description": "${role_view-realm}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes": {}
+ }
+ ],
+ "security-admin-console": [],
+ "admin-cli": [],
+ "account-console": [],
+ "broker": [
+ {
+ "id": "09571088-e666-437f-a2e5-1025ab1c2679",
+ "name": "read-token",
+ "description": "${role_read-token}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "2d47b1b5-8c05-4cfb-adac-000dff429b98",
+ "attributes": {}
+ }
+ ],
+ "account": [
+ {
+ "id": "5e1c1bd4-a134-4765-8f0b-753adc507e3f",
+ "name": "delete-account",
+ "description": "${role_delete-account}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes": {}
+ },
+ {
+ "id": "87f66ba3-e129-4b3d-a50c-1dbefb31c3e3",
+ "name": "view-applications",
+ "description": "${role_view-applications}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes": {}
+ },
+ {
+ "id": "21efa0ec-d716-49d7-b987-550b4158300c",
+ "name": "manage-account-links",
+ "description": "${role_manage-account-links}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes": {}
+ },
+ {
+ "id": "294862a6-637d-4993-9743-fab2ea7745d5",
+ "name": "view-groups",
+ "description": "${role_view-groups}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes": {}
+ },
+ {
+ "id": "ffd6f5d8-5f93-4824-9bb8-4a18bda8e65c",
+ "name": "manage-consent",
+ "description": "${role_manage-consent}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "account": [
+ "view-consent"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes": {}
+ },
+ {
+ "id": "7101cd26-567b-41a2-935d-6dd3c95447d4",
+ "name": "view-consent",
+ "description": "${role_view-consent}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes": {}
+ },
+ {
+ "id": "0b2fda0c-350c-4719-8485-74c4c9a14b4f",
+ "name": "manage-account",
+ "description": "${role_manage-account}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "account": [
+ "manage-account-links"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes": {}
+ },
+ {
+ "id": "66746e76-a6e9-4f17-8a53-c8485ffcbd54",
+ "name": "view-profile",
+ "description": "${role_view-profile}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes": {}
+ }
+ ]
+ }
+ },
+ "groups": [],
+ "defaultRole": {
+ "id": "480c5735-3615-4031-8af5-1a5941f6ed85",
+ "name": "default-roles-REALM_NAME_PLACEHOLDER",
+ "description": "${role_default-roles}",
+ "composite": true,
+ "clientRole": false,
+ "containerId": "dd63c101-0933-44ff-bd0d-6291b7b195ae"
+ },
+ "requiredCredentials": [
+ "password"
+ ],
+ "otpPolicyType": "totp",
+ "otpPolicyAlgorithm": "HmacSHA1",
+ "otpPolicyInitialCounter": 0,
+ "otpPolicyDigits": 6,
+ "otpPolicyLookAheadWindow": 1,
+ "otpPolicyPeriod": 30,
+ "otpPolicyCodeReusable": false,
+ "otpSupportedApplications": [
+ "totpAppFreeOTPName",
+ "totpAppGoogleName",
+ "totpAppMicrosoftAuthenticatorName"
+ ],
+ "localizationTexts": {},
+ "webAuthnPolicyRpEntityName": "keycloak",
+ "webAuthnPolicySignatureAlgorithms": [
+ "ES256"
+ ],
+ "webAuthnPolicyRpId": "",
+ "webAuthnPolicyAttestationConveyancePreference": "not specified",
+ "webAuthnPolicyAuthenticatorAttachment": "not specified",
+ "webAuthnPolicyRequireResidentKey": "not specified",
+ "webAuthnPolicyUserVerificationRequirement": "not specified",
+ "webAuthnPolicyCreateTimeout": 0,
+ "webAuthnPolicyAvoidSameAuthenticatorRegister": false,
+ "webAuthnPolicyAcceptableAaguids": [],
+ "webAuthnPolicyExtraOrigins": [],
+ "webAuthnPolicyPasswordlessRpEntityName": "keycloak",
+ "webAuthnPolicyPasswordlessSignatureAlgorithms": [
+ "ES256"
+ ],
+ "webAuthnPolicyPasswordlessRpId": "",
+ "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
+ "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
+ "webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
+ "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
+ "webAuthnPolicyPasswordlessCreateTimeout": 0,
+ "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
+ "webAuthnPolicyPasswordlessAcceptableAaguids": [],
+ "webAuthnPolicyPasswordlessExtraOrigins": [],
+ "scopeMappings": [
+ {
+ "clientScope": "offline_access",
+ "roles": [
+ "offline_access"
+ ]
+ }
+ ],
+ "clientScopeMappings": {
+ "account": [
+ {
+ "client": "account-console",
+ "roles": [
+ "manage-account",
+ "view-groups"
+ ]
+ }
+ ]
+ },
+ "clients": [
+ {
+ "id": "c9b64036-d306-481f-acf0-138f42e4714f",
+ "clientId": "account",
+ "name": "${client_account}",
+ "rootUrl": "${authBaseUrl}",
+ "baseUrl": "/realms/REALM_NAME_PLACEHOLDER/account/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/realms/REALM_NAME_PLACEHOLDER/account/*"
+ ],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "post.logout.redirect.uris": "+"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "roles",
+ "profile",
+ "basic",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "organization",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "fb5c35f5-62d6-4641-96f5-1e92fee5e4c9",
+ "clientId": "account-console",
+ "name": "${client_account-console}",
+ "rootUrl": "${authBaseUrl}",
+ "baseUrl": "/realms/REALM_NAME_PLACEHOLDER/account/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/realms/REALM_NAME_PLACEHOLDER/account/*"
+ ],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "post.logout.redirect.uris": "+",
+ "pkce.code.challenge.method": "S256"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "protocolMappers": [
+ {
+ "id": "26ccae04-fffd-4fb2-8c8b-a69331675dc4",
+ "name": "audience resolve",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-resolve-mapper",
+ "consentRequired": false,
+ "config": {}
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "roles",
+ "profile",
+ "basic",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "organization",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "83bcfb18-8a63-40e8-a318-2511e432b8f9",
+ "clientId": "admin-cli",
+ "name": "${client_admin-cli}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": false,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": true,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "roles",
+ "profile",
+ "basic",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "organization",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "2d47b1b5-8c05-4cfb-adac-000dff429b98",
+ "clientId": "broker",
+ "name": "${client_broker}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": true,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "roles",
+ "profile",
+ "basic",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "organization",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "clientId": "realm-management",
+ "name": "${client_realm-management}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": true,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "roles",
+ "profile",
+ "basic",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "organization",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "5e7102d7-cbc5-48f2-855b-6c49b7730bc5",
+ "clientId": "security-admin-console",
+ "name": "${client_security-admin-console}",
+ "rootUrl": "${authAdminUrl}",
+ "baseUrl": "/admin/REALM_NAME_PLACEHOLDER/console/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "redirectUris": [
+ "/admin/REALM_NAME_PLACEHOLDER/console/*"
+ ],
+ "webOrigins": [
+ "+"
+ ],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "post.logout.redirect.uris": "+",
+ "pkce.code.challenge.method": "S256"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "protocolMappers": [
+ {
+ "id": "f0dc4884-abd8-43b1-8daf-a4ea30af2c45",
+ "name": "locale",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "locale",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "locale",
+ "jsonType.label": "String"
+ }
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "roles",
+ "profile",
+ "basic",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "organization",
+ "microprofile-jwt"
+ ]
+ }
+ ],
+ "clientScopes": [
+ {
+ "id": "75c3c28e-9954-4591-ad9f-2fa561935969",
+ "name": "phone",
+ "description": "OpenID Connect built-in scope: phone",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "consent.screen.text": "${phoneScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "c1bd61d7-b43c-47b6-bb09-c8f1048626b9",
+ "name": "phone number",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "phoneNumber",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "phone_number",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "22570598-1102-4011-a257-914cf1c61cb9",
+ "name": "phone number verified",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "phoneNumberVerified",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "phone_number_verified",
+ "jsonType.label": "boolean"
+ }
+ }
+ ]
+ },
+ {
+ "id": "2b62b196-a141-4963-b0a8-7cf1a5e5d79d",
+ "name": "web-origins",
+ "description": "OpenID Connect scope for add allowed web origins to the access token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "consent.screen.text": "",
+ "display.on.consent.screen": "false"
+ },
+ "protocolMappers": [
+ {
+ "id": "8103b7d0-9a8f-42c3-8cd4-3c14ab4f45d6",
+ "name": "allowed web origins",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-allowed-origins-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "access.token.claim": "true"
+ }
+ }
+ ]
+ },
+ {
+ "id": "0c9b45df-7b86-498e-a50b-263c81516364",
+ "name": "email",
+ "description": "OpenID Connect built-in scope: email",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "consent.screen.text": "${emailScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "55a6275a-652a-4087-800f-b8a96a18f847",
+ "name": "email verified",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "emailVerified",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "email_verified",
+ "jsonType.label": "boolean"
+ }
+ },
+ {
+ "id": "5deee1be-1359-4700-b3eb-fda36f384c6c",
+ "name": "email",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "email",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "email",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "baefbd93-a03d-4dcf-a810-d130c4c52e34",
+ "name": "offline_access",
+ "description": "OpenID Connect built-in scope: offline_access",
+ "protocol": "openid-connect",
+ "attributes": {
+ "consent.screen.text": "${offlineAccessScopeConsentText}",
+ "display.on.consent.screen": "true"
+ }
+ },
+ {
+ "id": "d9afdfca-5d6a-4154-9cb4-ffbca2c9a0cd",
+ "name": "basic",
+ "description": "OpenID Connect scope for add all basic claims to the token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "false"
+ },
+ "protocolMappers": [
+ {
+ "id": "b4274c50-30bd-41b8-90cf-0226c3537325",
+ "name": "sub",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-sub-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "access.token.claim": "true"
+ }
+ },
+ {
+ "id": "9816cb0e-df86-47d8-8c6d-a6e1e728936d",
+ "name": "auth_time",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usersessionmodel-note-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.session.note": "AUTH_TIME",
+ "id.token.claim": "true",
+ "introspection.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "auth_time",
+ "jsonType.label": "long"
+ }
+ }
+ ]
+ },
+ {
+ "id": "c747bf13-7fef-4210-931f-5b925e66b762",
+ "name": "roles",
+ "description": "OpenID Connect scope for add user roles to the access token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "consent.screen.text": "${rolesScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "16806ab6-8445-4982-98c5-31d2027eef21",
+ "name": "audience resolve",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-resolve-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "access.token.claim": "true"
+ }
+ },
+ {
+ "id": "f84f3429-cb42-41b1-a1f0-b0ce18547f88",
+ "name": "client roles",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-client-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "foo",
+ "introspection.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "resource_access.${client_id}.roles",
+ "jsonType.label": "String",
+ "multivalued": "true"
+ }
+ },
+ {
+ "id": "bb42a14a-d1d2-469b-ba6a-5de818f9dc09",
+ "name": "realm roles",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-realm-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "foo",
+ "introspection.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "realm_access.roles",
+ "jsonType.label": "String",
+ "multivalued": "true"
+ }
+ }
+ ]
+ },
+ {
+ "id": "27c4af4a-ba34-4ab8-a3c7-d170c7600ce9",
+ "name": "address",
+ "description": "OpenID Connect built-in scope: address",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "consent.screen.text": "${addressScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "5fce34d7-0d3f-4ea3-9dd8-e9a935d7afc8",
+ "name": "address",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-address-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute.formatted": "formatted",
+ "user.attribute.country": "country",
+ "introspection.token.claim": "true",
+ "user.attribute.postal_code": "postal_code",
+ "userinfo.token.claim": "true",
+ "user.attribute.street": "street",
+ "id.token.claim": "true",
+ "user.attribute.region": "region",
+ "access.token.claim": "true",
+ "user.attribute.locality": "locality"
+ }
+ }
+ ]
+ },
+ {
+ "id": "54a28d98-624a-446a-bac6-987ef81e94a1",
+ "name": "microprofile-jwt",
+ "description": "Microprofile - JWT built-in scope",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "false"
+ },
+ "protocolMappers": [
+ {
+ "id": "d24b73e0-99ff-4529-822b-e34ca0f01e40",
+ "name": "groups",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-realm-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "multivalued": "true",
+ "user.attribute": "foo",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "groups",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "b8cb435d-b65e-4ea7-9fcf-47e68d12034c",
+ "name": "upn",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "username",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "upn",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "29e507c4-0d25-4c7e-bab2-445f02229498",
+ "name": "profile",
+ "description": "OpenID Connect built-in scope: profile",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "consent.screen.text": "${profileScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "38069a29-e1a5-418f-ae2c-d3eaad7aac72",
+ "name": "birthdate",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "birthdate",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "birthdate",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "75e8f35b-c264-413f-8329-6f1f75845754",
+ "name": "family name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "lastName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "family_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "14dbae81-967b-4293-a717-37e7c23849ce",
+ "name": "profile",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "profile",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "profile",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "b5e39b39-251b-4c7c-a495-f224fa668b8e",
+ "name": "username",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "username",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "preferred_username",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "8524ea93-38b8-4dc1-b1f0-d6a79be4aa49",
+ "name": "updated at",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "updatedAt",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "updated_at",
+ "jsonType.label": "long"
+ }
+ },
+ {
+ "id": "b43b0a85-5b62-4e24-bb44-d27ad870231e",
+ "name": "locale",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "locale",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "locale",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "3ec07ced-87fe-4a6f-a6d6-3aef1b70bb77",
+ "name": "nickname",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "nickname",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "nickname",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "279983b1-32c1-4240-a364-e1c5da2d1567",
+ "name": "picture",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "picture",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "picture",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "1308c0b3-f55e-4073-bef8-5f2ea0b6d7f1",
+ "name": "zoneinfo",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "zoneinfo",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "zoneinfo",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "ed828254-6168-41fd-95e8-bd0296499677",
+ "name": "gender",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "gender",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "gender",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "e008f950-539e-4484-9e49-a5ddc19a6247",
+ "name": "website",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "website",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "website",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "13145ef8-796d-44eb-9f91-6097872f7e43",
+ "name": "full name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-full-name-mapper",
+ "consentRequired": false,
+ "config": {
+ "id.token.claim": "true",
+ "introspection.token.claim": "true",
+ "access.token.claim": "true",
+ "userinfo.token.claim": "true"
+ }
+ },
+ {
+ "id": "44bd6fd2-002a-4f2e-9f67-85a10bdaaf91",
+ "name": "given name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "firstName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "given_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "af4a8bbb-eea2-4e92-a52e-db1b598cbdda",
+ "name": "middle name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "introspection.token.claim": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "middleName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "middle_name",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "e20000d2-97e9-4963-97ed-29c2493e88a1",
+ "name": "saml_organization",
+ "description": "Organization Membership",
+ "protocol": "saml",
+ "attributes": {
+ "display.on.consent.screen": "false"
+ },
+ "protocolMappers": [
+ {
+ "id": "f79afeba-4905-4acd-9a31-f5772a9cfaf5",
+ "name": "organization",
+ "protocol": "saml",
+ "protocolMapper": "saml-organization-membership-mapper",
+ "consentRequired": false,
+ "config": {}
+ }
+ ]
+ },
+ {
+ "id": "669d6b18-ad12-4ad4-bdac-2ccc9ba8ec19",
+ "name": "acr",
+ "description": "OpenID Connect scope for add acr (authentication context class reference) to the token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "false"
+ },
+ "protocolMappers": [
+ {
+ "id": "68c8bb60-3ade-4629-8e39-bacbbf1729a9",
+ "name": "acr loa level",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-acr-mapper",
+ "consentRequired": false,
+ "config": {
+ "id.token.claim": "true",
+ "introspection.token.claim": "true",
+ "access.token.claim": "true"
+ }
+ }
+ ]
+ },
+ {
+ "id": "e2644a46-32ce-4773-a502-4b49047ade5f",
+ "name": "role_list",
+ "description": "SAML role list",
+ "protocol": "saml",
+ "attributes": {
+ "consent.screen.text": "${samlRoleListScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "a16f5c5c-9b31-48e4-9a2a-b1102f116929",
+ "name": "role list",
+ "protocol": "saml",
+ "protocolMapper": "saml-role-list-mapper",
+ "consentRequired": false,
+ "config": {
+ "single": "false",
+ "attribute.nameformat": "Basic",
+ "attribute.name": "Role"
+ }
+ }
+ ]
+ },
+ {
+ "id": "f4a04ae3-7689-4162-a10d-80bf12c062b8",
+ "name": "organization",
+ "description": "Additional claims about the organization a subject belongs to",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "consent.screen.text": "${organizationScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "86d3a466-ec88-4260-8666-c80fb8a67616",
+ "name": "organization",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-organization-membership-mapper",
+ "consentRequired": false,
+ "config": {
+ "id.token.claim": "true",
+ "introspection.token.claim": "true",
+ "access.token.claim": "true"
+ }
+ }
+ ]
+ }
+ ],
+ "defaultDefaultClientScopes": [
+ "role_list",
+ "saml_organization",
+ "profile",
+ "email",
+ "roles",
+ "web-origins",
+ "acr",
+ "basic"
+ ],
+ "defaultOptionalClientScopes": [
+ "offline_access",
+ "address",
+ "phone",
+ "microprofile-jwt",
+ "organization"
+ ],
+ "browserSecurityHeaders": {
+ "contentSecurityPolicyReportOnly": "",
+ "xContentTypeOptions": "nosniff",
+ "referrerPolicy": "no-referrer",
+ "xRobotsTag": "none",
+ "xFrameOptions": "SAMEORIGIN",
+ "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+ "xXSSProtection": "1; mode=block",
+ "strictTransportSecurity": "max-age=31536000; includeSubDomains"
+ },
+ "smtpServer": {},
+ "eventsEnabled": false,
+ "eventsListeners": [
+ "jboss-logging"
+ ],
+ "enabledEventTypes": [],
+ "adminEventsEnabled": false,
+ "adminEventsDetailsEnabled": false,
+ "identityProviders": [],
+ "identityProviderMappers": [],
+ "components": {
+ "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [
+ {
+ "id": "fd92ba76-e8b6-473b-ae5b-324de55d1bec",
+ "name": "Consent Required",
+ "providerId": "consent-required",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {}
+ },
+ {
+ "id": "680d98da-7b39-42d7-addf-c8709f70e997",
+ "name": "Allowed Client Scopes",
+ "providerId": "allowed-client-templates",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "allow-default-scopes": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "134087bf-1b89-43a2-9ed8-e835bf24698e",
+ "name": "Max Clients Limit",
+ "providerId": "max-clients",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "max-clients": [
+ "200"
+ ]
+ }
+ },
+ {
+ "id": "6093461f-6bf9-47ef-902e-0cc6e795d468",
+ "name": "Allowed Protocol Mapper Types",
+ "providerId": "allowed-protocol-mappers",
+ "subType": "authenticated",
+ "subComponents": {},
+ "config": {
+ "allowed-protocol-mapper-types": [
+ "oidc-usermodel-attribute-mapper",
+ "saml-user-attribute-mapper",
+ "oidc-full-name-mapper",
+ "saml-role-list-mapper",
+ "oidc-sha256-pairwise-sub-mapper",
+ "saml-user-property-mapper",
+ "oidc-address-mapper",
+ "oidc-usermodel-property-mapper"
+ ]
+ }
+ },
+ {
+ "id": "da0f1531-50c5-4c32-91d6-78a49c83c8f9",
+ "name": "Trusted Hosts",
+ "providerId": "trusted-hosts",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "host-sending-registration-request-must-match": [
+ "true"
+ ],
+ "client-uris-must-match": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "ee589b19-fee3-43aa-a235-6ebad256fc88",
+ "name": "Allowed Protocol Mapper Types",
+ "providerId": "allowed-protocol-mappers",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "allowed-protocol-mapper-types": [
+ "oidc-address-mapper",
+ "oidc-usermodel-property-mapper",
+ "oidc-full-name-mapper",
+ "saml-user-attribute-mapper",
+ "oidc-sha256-pairwise-sub-mapper",
+ "saml-role-list-mapper",
+ "oidc-usermodel-attribute-mapper",
+ "saml-user-property-mapper"
+ ]
+ }
+ },
+ {
+ "id": "98947e9b-8db1-43a9-953b-b0a7a6529308",
+ "name": "Allowed Client Scopes",
+ "providerId": "allowed-client-templates",
+ "subType": "authenticated",
+ "subComponents": {},
+ "config": {
+ "allow-default-scopes": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "19309024-e8ed-41bf-aaab-120b77546970",
+ "name": "Full Scope Disabled",
+ "providerId": "scope",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {}
+ }
+ ],
+ "org.keycloak.keys.KeyProvider": [
+ {
+ "id": "6873ae62-f710-410f-adff-4529edacecd5",
+ "name": "hmac-generated-hs512",
+ "providerId": "hmac-generated",
+ "subComponents": {},
+ "config": {
+ "priority": [
+ "100"
+ ],
+ "algorithm": [
+ "HS512"
+ ]
+ }
+ },
+ {
+ "id": "acaf8c35-8426-4212-b476-9755e750cba8",
+ "name": "aes-generated",
+ "providerId": "aes-generated",
+ "subComponents": {},
+ "config": {
+ "priority": [
+ "100"
+ ]
+ }
+ },
+ {
+ "id": "79b45bb7-9f51-4a5d-9ddb-a38193869cf8",
+ "name": "rsa-enc-generated",
+ "providerId": "rsa-enc-generated",
+ "subComponents": {},
+ "config": {
+ "priority": [
+ "100"
+ ],
+ "algorithm": [
+ "RSA-OAEP"
+ ]
+ }
+ },
+ {
+ "id": "6d6fdef5-fc2a-4283-872b-78d43683405a",
+ "name": "rsa-generated",
+ "providerId": "rsa-generated",
+ "subComponents": {},
+ "config": {
+ "priority": [
+ "100"
+ ]
+ }
+ }
+ ]
+ },
+ "internationalizationEnabled": false,
+ "supportedLocales": [],
+ "authenticationFlows": [
+ {
+ "id": "820f56e1-92f9-489a-8d5b-435c3090d565",
+ "alias": "Account verification options",
+ "description": "Method with which to verity the existing account",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-email-verification",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Verify Existing Account by Re-authentication",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "485f4929-8cd5-4823-ab43-46632ff328f1",
+ "alias": "Browser - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-otp-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "7cd25178-93e4-40a1-85a3-a7eedd1eee58",
+ "alias": "Browser - Conditional Organization",
+ "description": "Flow to determine if the organization identity-first login is to be used",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "organization",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "13859544-1f4e-4d3a-9c59-160d72f1ef09",
+ "alias": "Direct Grant - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "direct-grant-validate-otp",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "95b03f52-3e9a-4745-9f2d-fa92024f892a",
+ "alias": "First Broker Login - Conditional Organization",
+ "description": "Flow to determine if the authenticator that adds organization members is to be used",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "idp-add-organization-member",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "e0b0819f-f839-4ac3-93bc-a6944d789c6b",
+ "alias": "First broker login - Conditional OTP",
+ "description": "Flow to determine if the OTP is required for the authentication",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-otp-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "a39f72d5-7336-48bf-9abd-c6247d3c5188",
+ "alias": "Handle Existing Account",
+ "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-confirm-link",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Account verification options",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "d0ebe092-0fd9-4884-9df2-0fc19560cf0a",
+ "alias": "Organization",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 10,
+ "autheticatorFlow": true,
+ "flowAlias": "Browser - Conditional Organization",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "7b9d4855-89f8-4df6-beda-bfb035f9a244",
+ "alias": "Reset - Conditional OTP",
+ "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "conditional-user-configured",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "reset-otp",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "df1575c6-b9cd-4342-8c85-c6376853866d",
+ "alias": "User creation or linking",
+ "description": "Flow for the existing/non-existing user alternatives",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticatorConfig": "create unique user config",
+ "authenticator": "idp-create-user-if-unique",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Handle Existing Account",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "10a02bfc-f238-4b94-abbd-7706c2f21b70",
+ "alias": "Verify Existing Account by Re-authentication",
+ "description": "Reauthentication of existing account",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "idp-username-password-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "First broker login - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "63965b58-1b62-4f3a-9fd3-7e3e3c4c3eed",
+ "alias": "browser",
+ "description": "browser based authentication",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "auth-cookie",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "auth-spnego",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "identity-provider-redirector",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 25,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 26,
+ "autheticatorFlow": true,
+ "flowAlias": "Organization",
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "ALTERNATIVE",
+ "priority": 30,
+ "autheticatorFlow": true,
+ "flowAlias": "forms",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "618c8052-b998-4181-85f3-6e171a8ad356",
+ "alias": "clients",
+ "description": "Base authentication for clients",
+ "providerId": "client-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "client-secret",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "client-jwt",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "client-secret-jwt",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 30,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "client-x509",
+ "authenticatorFlow": false,
+ "requirement": "ALTERNATIVE",
+ "priority": 40,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "ca3e691a-2326-450b-93d0-eb9929fc3745",
+ "alias": "direct grant",
+ "description": "OpenID Connect Resource Owner Grant",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "direct-grant-validate-username",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "direct-grant-validate-password",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 30,
+ "autheticatorFlow": true,
+ "flowAlias": "Direct Grant - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "e8c2f7fe-c611-4ef9-a062-8d6c3388f797",
+ "alias": "docker auth",
+ "description": "Used by Docker clients to authenticate against the IDP",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "docker-http-basic-authenticator",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "178a91fc-9bb6-43c2-88cc-5fd73afe2d75",
+ "alias": "first broker login",
+ "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticatorConfig": "review profile config",
+ "authenticator": "idp-review-profile",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "User creation or linking",
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 50,
+ "autheticatorFlow": true,
+ "flowAlias": "First Broker Login - Conditional Organization",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "4c38d67f-c298-4b46-aec8-df00f853e64a",
+ "alias": "forms",
+ "description": "Username, password, otp and other auth forms.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "auth-username-password-form",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 20,
+ "autheticatorFlow": true,
+ "flowAlias": "Browser - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "ee4ae8cd-0770-44a0-89c5-de1bb96971df",
+ "alias": "registration",
+ "description": "registration flow",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "registration-page-form",
+ "authenticatorFlow": true,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": true,
+ "flowAlias": "registration form",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "9af610f3-08e4-4a3a-a2f2-a85c9cc65f88",
+ "alias": "registration form",
+ "description": "registration form",
+ "providerId": "form-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "registration-user-creation",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "registration-password-action",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 50,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "registration-recaptcha-action",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 60,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "registration-terms-and-conditions",
+ "authenticatorFlow": false,
+ "requirement": "DISABLED",
+ "priority": 70,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "def02675-afb8-479b-9756-b6399c49a616",
+ "alias": "reset credentials",
+ "description": "Reset credentials for a user if they forgot their password or something",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "reset-credentials-choose-user",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "reset-credential-email",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticator": "reset-password",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 30,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ },
+ {
+ "authenticatorFlow": true,
+ "requirement": "CONDITIONAL",
+ "priority": 40,
+ "autheticatorFlow": true,
+ "flowAlias": "Reset - Conditional OTP",
+ "userSetupAllowed": false
+ }
+ ]
+ },
+ {
+ "id": "4da59173-6c48-4f89-a8f1-b9ffe3952641",
+ "alias": "saml ecp",
+ "description": "SAML ECP Profile Authentication Flow",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "http-basic-authenticator",
+ "authenticatorFlow": false,
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "autheticatorFlow": false,
+ "userSetupAllowed": false
+ }
+ ]
+ }
+ ],
+ "authenticatorConfig": [
+ {
+ "id": "5aab6c05-0143-49e2-a8a7-b886685e00b9",
+ "alias": "create unique user config",
+ "config": {
+ "require.password.update.after.registration": "false"
+ }
+ },
+ {
+ "id": "c00631ca-8122-41e7-bffc-6034063cc7b1",
+ "alias": "review profile config",
+ "config": {
+ "update.profile.on.first.login": "missing"
+ }
+ }
+ ],
+ "requiredActions": [
+ {
+ "alias": "CONFIGURE_TOTP",
+ "name": "Configure OTP",
+ "providerId": "CONFIGURE_TOTP",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 10,
+ "config": {}
+ },
+ {
+ "alias": "TERMS_AND_CONDITIONS",
+ "name": "Terms and Conditions",
+ "providerId": "TERMS_AND_CONDITIONS",
+ "enabled": false,
+ "defaultAction": false,
+ "priority": 20,
+ "config": {}
+ },
+ {
+ "alias": "UPDATE_PASSWORD",
+ "name": "Update Password",
+ "providerId": "UPDATE_PASSWORD",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 30,
+ "config": {}
+ },
+ {
+ "alias": "UPDATE_PROFILE",
+ "name": "Update Profile",
+ "providerId": "UPDATE_PROFILE",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 40,
+ "config": {}
+ },
+ {
+ "alias": "VERIFY_EMAIL",
+ "name": "Verify Email",
+ "providerId": "VERIFY_EMAIL",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 50,
+ "config": {}
+ },
+ {
+ "alias": "delete_account",
+ "name": "Delete Account",
+ "providerId": "delete_account",
+ "enabled": false,
+ "defaultAction": false,
+ "priority": 60,
+ "config": {}
+ },
+ {
+ "alias": "CONFIGURE_RECOVERY_AUTHN_CODES",
+ "name": "Recovery Authentication Codes",
+ "providerId": "CONFIGURE_RECOVERY_AUTHN_CODES",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 70,
+ "config": {}
+ },
+ {
+ "alias": "UPDATE_EMAIL",
+ "name": "Update Email",
+ "providerId": "UPDATE_EMAIL",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 70,
+ "config": {}
+ },
+ {
+ "alias": "webauthn-register",
+ "name": "Webauthn Register",
+ "providerId": "webauthn-register",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 70,
+ "config": {}
+ },
+ {
+ "alias": "webauthn-register-passwordless",
+ "name": "Webauthn Register Passwordless",
+ "providerId": "webauthn-register-passwordless",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 80,
+ "config": {}
+ },
+ {
+ "alias": "VERIFY_PROFILE",
+ "name": "Verify Profile",
+ "providerId": "VERIFY_PROFILE",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 90,
+ "config": {}
+ },
+ {
+ "alias": "delete_credential",
+ "name": "Delete Credential",
+ "providerId": "delete_credential",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 100,
+ "config": {}
+ },
+ {
+ "alias": "update_user_locale",
+ "name": "Update User Locale",
+ "providerId": "update_user_locale",
+ "enabled": true,
+ "defaultAction": false,
+ "priority": 1000,
+ "config": {}
+ }
+ ],
+ "browserFlow": "browser",
+ "registrationFlow": "registration",
+ "directGrantFlow": "direct grant",
+ "resetCredentialsFlow": "reset credentials",
+ "clientAuthenticationFlow": "clients",
+ "dockerAuthenticationFlow": "docker auth",
+ "firstBrokerLoginFlow": "first broker login",
+ "attributes": {
+ "cibaBackchannelTokenDeliveryMode": "poll",
+ "cibaExpiresIn": "120",
+ "cibaAuthRequestedUserHint": "login_hint",
+ "oauth2DeviceCodeLifespan": "600",
+ "oauth2DevicePollingInterval": "5",
+ "parRequestUriLifespan": "60",
+ "cibaInterval": "5",
+ "realmReusableOtpCode": "false"
+ },
+ "keycloakVersion": "25.0.5",
+ "userManagedAccessAllowed": false,
+ "organizationsEnabled": false,
+ "clientProfiles": {
+ "profiles": []
+ },
+ "clientPolicies": {
+ "policies": []
+ }
+}
diff --git a/src/main/resources/baseline/26.0.5/client/client.json b/src/main/resources/baseline/26.0.5/client/client.json
new file mode 100644
index 000000000..9da0a47e7
--- /dev/null
+++ b/src/main/resources/baseline/26.0.5/client/client.json
@@ -0,0 +1,60 @@
+{
+ "clientId": "reference-client",
+ "name": "",
+ "description": "",
+ "rootUrl": "",
+ "adminUrl": "",
+ "baseUrl": "",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "cjQ7lt37eAxeBRDzmLDsML89l1F6MHeY",
+ "redirectUris": [
+ "/*"
+ ],
+ "webOrigins": [
+ "/*"
+ ],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": true,
+ "protocol": "openid-connect",
+ "attributes": {
+ "realm_client": "false",
+ "oidc.ciba.grant.enabled": "false",
+ "client.secret.creation.time": "1726783534",
+ "backchannel.logout.session.required": "true",
+ "oauth2.device.authorization.grant.enabled": "false",
+ "backchannel.logout.revoke.offline.tokens": "false"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": true,
+ "nodeReRegistrationTimeout": -1,
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "roles",
+ "profile",
+ "basic",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "organization",
+ "microprofile-jwt"
+ ],
+ "access": {
+ "view": true,
+ "configure": true,
+ "manage": true
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/baseline/26.0.5/realm/realm.json b/src/main/resources/baseline/26.0.5/realm/realm.json
new file mode 100644
index 000000000..68cd9129a
--- /dev/null
+++ b/src/main/resources/baseline/26.0.5/realm/realm.json
@@ -0,0 +1,1965 @@
+{
+ "id" : "dd63c101-0933-44ff-bd0d-6291b7b195ae",
+ "realm" : "REALM_NAME_PLACEHOLDER",
+ "notBefore" : 0,
+ "defaultSignatureAlgorithm" : "RS256",
+ "revokeRefreshToken" : false,
+ "refreshTokenMaxReuse" : 0,
+ "accessTokenLifespan" : 300,
+ "accessTokenLifespanForImplicitFlow" : 900,
+ "ssoSessionIdleTimeout" : 1800,
+ "ssoSessionMaxLifespan" : 36000,
+ "ssoSessionIdleTimeoutRememberMe" : 0,
+ "ssoSessionMaxLifespanRememberMe" : 0,
+ "offlineSessionIdleTimeout" : 2592000,
+ "offlineSessionMaxLifespanEnabled" : false,
+ "offlineSessionMaxLifespan" : 5184000,
+ "clientSessionIdleTimeout" : 0,
+ "clientSessionMaxLifespan" : 0,
+ "clientOfflineSessionIdleTimeout" : 0,
+ "clientOfflineSessionMaxLifespan" : 0,
+ "accessCodeLifespan" : 60,
+ "accessCodeLifespanUserAction" : 300,
+ "accessCodeLifespanLogin" : 1800,
+ "actionTokenGeneratedByAdminLifespan" : 43200,
+ "actionTokenGeneratedByUserLifespan" : 300,
+ "oauth2DeviceCodeLifespan" : 600,
+ "oauth2DevicePollingInterval" : 5,
+ "enabled" : true,
+ "sslRequired" : "external",
+ "registrationAllowed" : false,
+ "registrationEmailAsUsername" : false,
+ "rememberMe" : false,
+ "verifyEmail" : false,
+ "loginWithEmailAllowed" : true,
+ "duplicateEmailsAllowed" : false,
+ "resetPasswordAllowed" : false,
+ "editUsernameAllowed" : false,
+ "bruteForceProtected" : false,
+ "permanentLockout" : false,
+ "maxTemporaryLockouts" : 0,
+ "bruteForceStrategy" : "MULTIPLE",
+ "maxFailureWaitSeconds" : 900,
+ "minimumQuickLoginWaitSeconds" : 60,
+ "waitIncrementSeconds" : 60,
+ "quickLoginCheckMilliSeconds" : 1000,
+ "maxDeltaTimeSeconds" : 43200,
+ "failureFactor" : 30,
+ "roles" : {
+ "realm" : [ {
+ "id" : "9580c9da-0c78-43c6-82b6-f1694db9bfa2",
+ "name" : "uma_authorization",
+ "description" : "${role_uma_authorization}",
+ "composite" : false,
+ "clientRole" : false,
+ "containerId" : "dd63c101-0933-44ff-bd0d-6291b7b195ae",
+ "attributes" : { }
+ }, {
+ "id" : "480c5735-3615-4031-8af5-1a5941f6ed85",
+ "name" : "default-roles-REALM_NAME_PLACEHOLDER",
+ "description" : "${role_default-roles}",
+ "composite" : true,
+ "composites" : {
+ "realm" : [ "offline_access", "uma_authorization" ],
+ "client" : {
+ "account" : [ "manage-account", "view-profile" ]
+ }
+ },
+ "clientRole" : false,
+ "containerId" : "dd63c101-0933-44ff-bd0d-6291b7b195ae",
+ "attributes" : { }
+ }, {
+ "id" : "acdaa4dc-3b37-4ef8-bc96-61d0bad24273",
+ "name" : "offline_access",
+ "description" : "${role_offline-access}",
+ "composite" : false,
+ "clientRole" : false,
+ "containerId" : "dd63c101-0933-44ff-bd0d-6291b7b195ae",
+ "attributes" : { }
+ } ],
+ "client" : {
+ "realm-management" : [ {
+ "id" : "cfb49ecc-087c-45ee-82b9-c04f09598ce7",
+ "name" : "manage-users",
+ "description" : "${role_manage-users}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "6fa23d54-426d-43fe-8fe9-1ea3eb901101",
+ "name" : "view-authorization",
+ "description" : "${role_view-authorization}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "98f722da-2e2b-4607-9cee-cfbf53593f36",
+ "name" : "impersonation",
+ "description" : "${role_impersonation}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "831f2cef-957c-4eaf-a309-e04ba25aed17",
+ "name" : "view-clients",
+ "description" : "${role_view-clients}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "realm-management" : [ "query-clients" ]
+ }
+ },
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "ad3da993-2344-45ab-adda-805025fe1c0e",
+ "name" : "create-client",
+ "description" : "${role_create-client}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "9144db3e-b609-4afa-a7fb-86340e7c4943",
+ "name" : "manage-events",
+ "description" : "${role_manage-events}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "64ce3225-b08c-45ac-b4da-a0f78ff53054",
+ "name" : "query-clients",
+ "description" : "${role_query-clients}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "bff7eea4-ef17-4873-8712-8461ac4a3ecb",
+ "name" : "query-groups",
+ "description" : "${role_query-groups}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "a8a226e0-fbdc-4a67-b4d8-53a945fad25c",
+ "name" : "query-realms",
+ "description" : "${role_query-realms}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "b22b71b1-a8dd-4aad-a879-a266a27f5da0",
+ "name" : "realm-admin",
+ "description" : "${role_realm-admin}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "realm-management" : [ "manage-users", "view-authorization", "view-clients", "impersonation", "create-client", "manage-events", "query-clients", "query-groups", "query-realms", "view-users", "view-events", "manage-clients", "manage-identity-providers", "manage-realm", "query-users", "view-identity-providers", "manage-authorization", "view-realm" ]
+ }
+ },
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "56940251-b312-4ba5-8897-80770420fbc5",
+ "name" : "view-users",
+ "description" : "${role_view-users}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "realm-management" : [ "query-users", "query-groups" ]
+ }
+ },
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "8080db13-00bd-4091-a36d-eb9a727c6e06",
+ "name" : "manage-clients",
+ "description" : "${role_manage-clients}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "c637da23-2962-43fd-ad60-3d722b83c991",
+ "name" : "manage-identity-providers",
+ "description" : "${role_manage-identity-providers}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "77347d4e-c2ba-4590-b9d7-2f6caacfb9c2",
+ "name" : "view-events",
+ "description" : "${role_view-events}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "eee3badf-8cfd-45e0-95e2-b31c4246b2ff",
+ "name" : "manage-realm",
+ "description" : "${role_manage-realm}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "62028465-2dbc-438c-a3da-d1028fc064cb",
+ "name" : "query-users",
+ "description" : "${role_query-users}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "c3d108ea-11e7-4c03-9e22-165e27a37b29",
+ "name" : "view-identity-providers",
+ "description" : "${role_view-identity-providers}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "f104fd30-19bc-41f1-8d1d-8ac8060f4d3e",
+ "name" : "manage-authorization",
+ "description" : "${role_manage-authorization}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ }, {
+ "id" : "291747a2-0c07-4265-afe8-08a195e6d029",
+ "name" : "view-realm",
+ "description" : "${role_view-realm}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "attributes" : { }
+ } ],
+ "security-admin-console" : [ ],
+ "admin-cli" : [ ],
+ "account-console" : [ ],
+ "broker" : [ {
+ "id" : "09571088-e666-437f-a2e5-1025ab1c2679",
+ "name" : "read-token",
+ "description" : "${role_read-token}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2d47b1b5-8c05-4cfb-adac-000dff429b98",
+ "attributes" : { }
+ } ],
+ "account" : [ {
+ "id" : "5e1c1bd4-a134-4765-8f0b-753adc507e3f",
+ "name" : "delete-account",
+ "description" : "${role_delete-account}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes" : { }
+ }, {
+ "id" : "87f66ba3-e129-4b3d-a50c-1dbefb31c3e3",
+ "name" : "view-applications",
+ "description" : "${role_view-applications}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes" : { }
+ }, {
+ "id" : "21efa0ec-d716-49d7-b987-550b4158300c",
+ "name" : "manage-account-links",
+ "description" : "${role_manage-account-links}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes" : { }
+ }, {
+ "id" : "294862a6-637d-4993-9743-fab2ea7745d5",
+ "name" : "view-groups",
+ "description" : "${role_view-groups}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes" : { }
+ }, {
+ "id" : "ffd6f5d8-5f93-4824-9bb8-4a18bda8e65c",
+ "name" : "manage-consent",
+ "description" : "${role_manage-consent}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "account" : [ "view-consent" ]
+ }
+ },
+ "clientRole" : true,
+ "containerId" : "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes" : { }
+ }, {
+ "id" : "7101cd26-567b-41a2-935d-6dd3c95447d4",
+ "name" : "view-consent",
+ "description" : "${role_view-consent}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes" : { }
+ }, {
+ "id" : "0b2fda0c-350c-4719-8485-74c4c9a14b4f",
+ "name" : "manage-account",
+ "description" : "${role_manage-account}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "account" : [ "manage-account-links" ]
+ }
+ },
+ "clientRole" : true,
+ "containerId" : "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes" : { }
+ }, {
+ "id" : "66746e76-a6e9-4f17-8a53-c8485ffcbd54",
+ "name" : "view-profile",
+ "description" : "${role_view-profile}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "c9b64036-d306-481f-acf0-138f42e4714f",
+ "attributes" : { }
+ } ]
+ }
+ },
+ "groups" : [ ],
+ "defaultRole" : {
+ "id" : "480c5735-3615-4031-8af5-1a5941f6ed85",
+ "name" : "default-roles-REALM_NAME_PLACEHOLDER",
+ "description" : "${role_default-roles}",
+ "composite" : true,
+ "clientRole" : false,
+ "containerId" : "dd63c101-0933-44ff-bd0d-6291b7b195ae"
+ },
+ "requiredCredentials" : [ "password" ],
+ "otpPolicyType" : "totp",
+ "otpPolicyAlgorithm" : "HmacSHA1",
+ "otpPolicyInitialCounter" : 0,
+ "otpPolicyDigits" : 6,
+ "otpPolicyLookAheadWindow" : 1,
+ "otpPolicyPeriod" : 30,
+ "otpPolicyCodeReusable" : false,
+ "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName" ],
+ "localizationTexts" : { },
+ "webAuthnPolicyRpEntityName" : "keycloak",
+ "webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
+ "webAuthnPolicyRpId" : "",
+ "webAuthnPolicyAttestationConveyancePreference" : "not specified",
+ "webAuthnPolicyAuthenticatorAttachment" : "not specified",
+ "webAuthnPolicyRequireResidentKey" : "not specified",
+ "webAuthnPolicyUserVerificationRequirement" : "not specified",
+ "webAuthnPolicyCreateTimeout" : 0,
+ "webAuthnPolicyAvoidSameAuthenticatorRegister" : false,
+ "webAuthnPolicyAcceptableAaguids" : [ ],
+ "webAuthnPolicyExtraOrigins" : [ ],
+ "webAuthnPolicyPasswordlessRpEntityName" : "keycloak",
+ "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ],
+ "webAuthnPolicyPasswordlessRpId" : "",
+ "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified",
+ "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified",
+ "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified",
+ "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified",
+ "webAuthnPolicyPasswordlessCreateTimeout" : 0,
+ "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false,
+ "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ],
+ "webAuthnPolicyPasswordlessExtraOrigins" : [ ],
+ "scopeMappings" : [ {
+ "clientScope" : "offline_access",
+ "roles" : [ "offline_access" ]
+ } ],
+ "clientScopeMappings" : {
+ "account" : [ {
+ "client" : "account-console",
+ "roles" : [ "manage-account", "view-groups" ]
+ } ]
+ },
+ "clients" : [ {
+ "id" : "c9b64036-d306-481f-acf0-138f42e4714f",
+ "clientId" : "account",
+ "name" : "${client_account}",
+ "rootUrl" : "${authBaseUrl}",
+ "baseUrl" : "/realms/REALM_NAME_PLACEHOLDER/account/",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ "/realms/REALM_NAME_PLACEHOLDER/account/*" ],
+ "webOrigins" : [ ],
+ "notBefore" : 0,
+ "bearerOnly" : false,
+ "consentRequired" : false,
+ "standardFlowEnabled" : true,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : false,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : true,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "realm_client" : "false",
+ "post.logout.redirect.uris" : "+"
+ },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : false,
+ "nodeReRegistrationTimeout" : 0,
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "organization", "microprofile-jwt" ]
+ }, {
+ "id" : "fb5c35f5-62d6-4641-96f5-1e92fee5e4c9",
+ "clientId" : "account-console",
+ "name" : "${client_account-console}",
+ "rootUrl" : "${authBaseUrl}",
+ "baseUrl" : "/realms/REALM_NAME_PLACEHOLDER/account/",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ "/realms/REALM_NAME_PLACEHOLDER/account/*" ],
+ "webOrigins" : [ ],
+ "notBefore" : 0,
+ "bearerOnly" : false,
+ "consentRequired" : false,
+ "standardFlowEnabled" : true,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : false,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : true,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "realm_client" : "false",
+ "post.logout.redirect.uris" : "+",
+ "pkce.code.challenge.method" : "S256"
+ },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : false,
+ "nodeReRegistrationTimeout" : 0,
+ "protocolMappers" : [ {
+ "id" : "26ccae04-fffd-4fb2-8c8b-a69331675dc4",
+ "name" : "audience resolve",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-audience-resolve-mapper",
+ "consentRequired" : false,
+ "config" : { }
+ } ],
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "organization", "microprofile-jwt" ]
+ }, {
+ "id" : "83bcfb18-8a63-40e8-a318-2511e432b8f9",
+ "clientId" : "admin-cli",
+ "name" : "${client_admin-cli}",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ ],
+ "webOrigins" : [ ],
+ "notBefore" : 0,
+ "bearerOnly" : false,
+ "consentRequired" : false,
+ "standardFlowEnabled" : false,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : true,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : true,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "realm_client" : "false",
+ "client.use.lightweight.access.token.enabled" : "true",
+ "post.logout.redirect.uris" : "+"
+ },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : true,
+ "nodeReRegistrationTimeout" : 0,
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "organization", "microprofile-jwt" ]
+ }, {
+ "id" : "2d47b1b5-8c05-4cfb-adac-000dff429b98",
+ "clientId" : "broker",
+ "name" : "${client_broker}",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ ],
+ "webOrigins" : [ ],
+ "notBefore" : 0,
+ "bearerOnly" : true,
+ "consentRequired" : false,
+ "standardFlowEnabled" : true,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : false,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : false,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "realm_client" : "true",
+ "post.logout.redirect.uris" : "+"
+ },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : false,
+ "nodeReRegistrationTimeout" : 0,
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "organization", "microprofile-jwt" ]
+ }, {
+ "id" : "dabfe89e-a20a-4502-81ae-6effe456c884",
+ "clientId" : "realm-management",
+ "name" : "${client_realm-management}",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ ],
+ "webOrigins" : [ ],
+ "notBefore" : 0,
+ "bearerOnly" : true,
+ "consentRequired" : false,
+ "standardFlowEnabled" : true,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : false,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : false,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "realm_client" : "true",
+ "post.logout.redirect.uris" : "+"
+ },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : false,
+ "nodeReRegistrationTimeout" : 0,
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "organization", "microprofile-jwt" ]
+ }, {
+ "id" : "5e7102d7-cbc5-48f2-855b-6c49b7730bc5",
+ "clientId" : "security-admin-console",
+ "name" : "${client_security-admin-console}",
+ "rootUrl" : "${authAdminUrl}",
+ "baseUrl" : "/admin/REALM_NAME_PLACEHOLDER/console/",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ "/admin/REALM_NAME_PLACEHOLDER/console/*" ],
+ "webOrigins" : [ "+" ],
+ "notBefore" : 0,
+ "bearerOnly" : false,
+ "consentRequired" : false,
+ "standardFlowEnabled" : true,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : false,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : true,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "realm_client" : "false",
+ "client.use.lightweight.access.token.enabled" : "true",
+ "post.logout.redirect.uris" : "+",
+ "pkce.code.challenge.method" : "S256"
+ },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : true,
+ "nodeReRegistrationTimeout" : 0,
+ "protocolMappers" : [ {
+ "id" : "f0dc4884-abd8-43b1-8daf-a4ea30af2c45",
+ "name" : "locale",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "locale",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "locale",
+ "jsonType.label" : "String"
+ }
+ } ],
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "organization", "microprofile-jwt" ]
+ } ],
+ "clientScopes" : [ {
+ "id" : "75c3c28e-9954-4591-ad9f-2fa561935969",
+ "name" : "phone",
+ "description" : "OpenID Connect built-in scope: phone",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${phoneScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "c1bd61d7-b43c-47b6-bb09-c8f1048626b9",
+ "name" : "phone number",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "phoneNumber",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "phone_number",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "22570598-1102-4011-a257-914cf1c61cb9",
+ "name" : "phone number verified",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "phoneNumberVerified",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "phone_number_verified",
+ "jsonType.label" : "boolean"
+ }
+ } ]
+ }, {
+ "id" : "2b62b196-a141-4963-b0a8-7cf1a5e5d79d",
+ "name" : "web-origins",
+ "description" : "OpenID Connect scope for add allowed web origins to the access token",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "false",
+ "consent.screen.text" : "",
+ "display.on.consent.screen" : "false"
+ },
+ "protocolMappers" : [ {
+ "id" : "8103b7d0-9a8f-42c3-8cd4-3c14ab4f45d6",
+ "name" : "allowed web origins",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-allowed-origins-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true"
+ }
+ } ]
+ }, {
+ "id" : "0c9b45df-7b86-498e-a50b-263c81516364",
+ "name" : "email",
+ "description" : "OpenID Connect built-in scope: email",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${emailScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "55a6275a-652a-4087-800f-b8a96a18f847",
+ "name" : "email verified",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-property-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "emailVerified",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "email_verified",
+ "jsonType.label" : "boolean"
+ }
+ }, {
+ "id" : "5deee1be-1359-4700-b3eb-fda36f384c6c",
+ "name" : "email",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "email",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "email",
+ "jsonType.label" : "String"
+ }
+ } ]
+ }, {
+ "id" : "baefbd93-a03d-4dcf-a810-d130c4c52e34",
+ "name" : "offline_access",
+ "description" : "OpenID Connect built-in scope: offline_access",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "consent.screen.text" : "${offlineAccessScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ }
+ }, {
+ "id" : "d9afdfca-5d6a-4154-9cb4-ffbca2c9a0cd",
+ "name" : "basic",
+ "description" : "OpenID Connect scope for add all basic claims to the token",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "false",
+ "display.on.consent.screen" : "false"
+ },
+ "protocolMappers" : [ {
+ "id" : "b4274c50-30bd-41b8-90cf-0226c3537325",
+ "name" : "sub",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-sub-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true"
+ }
+ }, {
+ "id" : "9816cb0e-df86-47d8-8c6d-a6e1e728936d",
+ "name" : "auth_time",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "user.session.note" : "AUTH_TIME",
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "auth_time",
+ "jsonType.label" : "long"
+ }
+ } ]
+ }, {
+ "id" : "c747bf13-7fef-4210-931f-5b925e66b762",
+ "name" : "roles",
+ "description" : "OpenID Connect scope for add user roles to the access token",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "false",
+ "consent.screen.text" : "${rolesScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "16806ab6-8445-4982-98c5-31d2027eef21",
+ "name" : "audience resolve",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-audience-resolve-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true"
+ }
+ }, {
+ "id" : "f84f3429-cb42-41b1-a1f0-b0ce18547f88",
+ "name" : "client roles",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-client-role-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "user.attribute" : "foo",
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "resource_access.${client_id}.roles",
+ "jsonType.label" : "String",
+ "multivalued" : "true"
+ }
+ }, {
+ "id" : "bb42a14a-d1d2-469b-ba6a-5de818f9dc09",
+ "name" : "realm roles",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "user.attribute" : "foo",
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "realm_access.roles",
+ "jsonType.label" : "String",
+ "multivalued" : "true"
+ }
+ } ]
+ }, {
+ "id" : "27c4af4a-ba34-4ab8-a3c7-d170c7600ce9",
+ "name" : "address",
+ "description" : "OpenID Connect built-in scope: address",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${addressScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "5fce34d7-0d3f-4ea3-9dd8-e9a935d7afc8",
+ "name" : "address",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-address-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "user.attribute.formatted" : "formatted",
+ "user.attribute.country" : "country",
+ "introspection.token.claim" : "true",
+ "user.attribute.postal_code" : "postal_code",
+ "userinfo.token.claim" : "true",
+ "user.attribute.street" : "street",
+ "id.token.claim" : "true",
+ "user.attribute.region" : "region",
+ "access.token.claim" : "true",
+ "user.attribute.locality" : "locality"
+ }
+ } ]
+ }, {
+ "id" : "54a28d98-624a-446a-bac6-987ef81e94a1",
+ "name" : "microprofile-jwt",
+ "description" : "Microprofile - JWT built-in scope",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "display.on.consent.screen" : "false"
+ },
+ "protocolMappers" : [ {
+ "id" : "d24b73e0-99ff-4529-822b-e34ca0f01e40",
+ "name" : "groups",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "multivalued" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "foo",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "groups",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "b8cb435d-b65e-4ea7-9fcf-47e68d12034c",
+ "name" : "upn",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "username",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "upn",
+ "jsonType.label" : "String"
+ }
+ } ]
+ }, {
+ "id" : "29e507c4-0d25-4c7e-bab2-445f02229498",
+ "name" : "profile",
+ "description" : "OpenID Connect built-in scope: profile",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${profileScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "38069a29-e1a5-418f-ae2c-d3eaad7aac72",
+ "name" : "birthdate",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "birthdate",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "birthdate",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "75e8f35b-c264-413f-8329-6f1f75845754",
+ "name" : "family name",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "lastName",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "family_name",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "14dbae81-967b-4293-a717-37e7c23849ce",
+ "name" : "profile",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "profile",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "profile",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "b5e39b39-251b-4c7c-a495-f224fa668b8e",
+ "name" : "username",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "username",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "preferred_username",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "8524ea93-38b8-4dc1-b1f0-d6a79be4aa49",
+ "name" : "updated at",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "updatedAt",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "updated_at",
+ "jsonType.label" : "long"
+ }
+ }, {
+ "id" : "b43b0a85-5b62-4e24-bb44-d27ad870231e",
+ "name" : "locale",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "locale",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "locale",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "3ec07ced-87fe-4a6f-a6d6-3aef1b70bb77",
+ "name" : "nickname",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "nickname",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "nickname",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "279983b1-32c1-4240-a364-e1c5da2d1567",
+ "name" : "picture",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "picture",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "picture",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "1308c0b3-f55e-4073-bef8-5f2ea0b6d7f1",
+ "name" : "zoneinfo",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "zoneinfo",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "zoneinfo",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "ed828254-6168-41fd-95e8-bd0296499677",
+ "name" : "gender",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "gender",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "gender",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "e008f950-539e-4484-9e49-a5ddc19a6247",
+ "name" : "website",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "website",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "website",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "13145ef8-796d-44eb-9f91-6097872f7e43",
+ "name" : "full name",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-full-name-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "id.token.claim" : "true",
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true",
+ "userinfo.token.claim" : "true"
+ }
+ }, {
+ "id" : "44bd6fd2-002a-4f2e-9f67-85a10bdaaf91",
+ "name" : "given name",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "firstName",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "given_name",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "af4a8bbb-eea2-4e92-a52e-db1b598cbdda",
+ "name" : "middle name",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "middleName",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "middle_name",
+ "jsonType.label" : "String"
+ }
+ } ]
+ }, {
+ "id" : "e20000d2-97e9-4963-97ed-29c2493e88a1",
+ "name" : "saml_organization",
+ "description" : "Organization Membership",
+ "protocol" : "saml",
+ "attributes" : {
+ "display.on.consent.screen" : "false"
+ },
+ "protocolMappers" : [ {
+ "id" : "f79afeba-4905-4acd-9a31-f5772a9cfaf5",
+ "name" : "organization",
+ "protocol" : "saml",
+ "protocolMapper" : "saml-organization-membership-mapper",
+ "consentRequired" : false,
+ "config" : { }
+ } ]
+ }, {
+ "id" : "669d6b18-ad12-4ad4-bdac-2ccc9ba8ec19",
+ "name" : "acr",
+ "description" : "OpenID Connect scope for add acr (authentication context class reference) to the token",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "false",
+ "display.on.consent.screen" : "false"
+ },
+ "protocolMappers" : [ {
+ "id" : "68c8bb60-3ade-4629-8e39-bacbbf1729a9",
+ "name" : "acr loa level",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-acr-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "id.token.claim" : "true",
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true",
+ "userinfo.token.claim" : "true"
+ }
+ } ]
+ }, {
+ "id" : "e2644a46-32ce-4773-a502-4b49047ade5f",
+ "name" : "role_list",
+ "description" : "SAML role list",
+ "protocol" : "saml",
+ "attributes" : {
+ "consent.screen.text" : "${samlRoleListScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "a16f5c5c-9b31-48e4-9a2a-b1102f116929",
+ "name" : "role list",
+ "protocol" : "saml",
+ "protocolMapper" : "saml-role-list-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "single" : "false",
+ "attribute.nameformat" : "Basic",
+ "attribute.name" : "Role"
+ }
+ } ]
+ }, {
+ "id" : "f4a04ae3-7689-4162-a10d-80bf12c062b8",
+ "name" : "organization",
+ "description" : "Additional claims about the organization a subject belongs to",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${organizationScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "86d3a466-ec88-4260-8666-c80fb8a67616",
+ "name" : "organization",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-organization-membership-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "id.token.claim" : "true",
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true",
+ "userinfo.token.claim" : "true"
+ }
+ } ]
+ } ],
+ "defaultDefaultClientScopes" : [ "role_list", "saml_organization", "profile", "email", "roles", "web-origins", "acr", "basic" ],
+ "defaultOptionalClientScopes" : [ "offline_access", "address", "phone", "microprofile-jwt", "organization" ],
+ "browserSecurityHeaders" : {
+ "contentSecurityPolicyReportOnly" : "",
+ "xContentTypeOptions" : "nosniff",
+ "referrerPolicy" : "no-referrer",
+ "xRobotsTag" : "none",
+ "xFrameOptions" : "SAMEORIGIN",
+ "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+ "xXSSProtection" : "1; mode=block",
+ "strictTransportSecurity" : "max-age=31536000; includeSubDomains"
+ },
+ "smtpServer" : { },
+ "eventsEnabled" : false,
+ "eventsListeners" : [ "jboss-logging" ],
+ "enabledEventTypes" : [ ],
+ "adminEventsEnabled" : false,
+ "adminEventsDetailsEnabled" : false,
+ "identityProviders" : [ ],
+ "identityProviderMappers" : [ ],
+ "components" : {
+ "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ {
+ "id" : "fd92ba76-e8b6-473b-ae5b-324de55d1bec",
+ "name" : "Consent Required",
+ "providerId" : "consent-required",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : { }
+ }, {
+ "id" : "680d98da-7b39-42d7-addf-c8709f70e997",
+ "name" : "Allowed Client Scopes",
+ "providerId" : "allowed-client-templates",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : {
+ "allow-default-scopes" : [ "true" ]
+ }
+ }, {
+ "id" : "134087bf-1b89-43a2-9ed8-e835bf24698e",
+ "name" : "Max Clients Limit",
+ "providerId" : "max-clients",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : {
+ "max-clients" : [ "200" ]
+ }
+ }, {
+ "id" : "6093461f-6bf9-47ef-902e-0cc6e795d468",
+ "name" : "Allowed Protocol Mapper Types",
+ "providerId" : "allowed-protocol-mappers",
+ "subType" : "authenticated",
+ "subComponents" : { },
+ "config" : {
+ "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-attribute-mapper", "saml-role-list-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper" ]
+ }
+ }, {
+ "id" : "da0f1531-50c5-4c32-91d6-78a49c83c8f9",
+ "name" : "Trusted Hosts",
+ "providerId" : "trusted-hosts",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : {
+ "host-sending-registration-request-must-match" : [ "true" ],
+ "client-uris-must-match" : [ "true" ]
+ }
+ }, {
+ "id" : "ee589b19-fee3-43aa-a235-6ebad256fc88",
+ "name" : "Allowed Protocol Mapper Types",
+ "providerId" : "allowed-protocol-mappers",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : {
+ "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper" ]
+ }
+ }, {
+ "id" : "98947e9b-8db1-43a9-953b-b0a7a6529308",
+ "name" : "Allowed Client Scopes",
+ "providerId" : "allowed-client-templates",
+ "subType" : "authenticated",
+ "subComponents" : { },
+ "config" : {
+ "allow-default-scopes" : [ "true" ]
+ }
+ }, {
+ "id" : "19309024-e8ed-41bf-aaab-120b77546970",
+ "name" : "Full Scope Disabled",
+ "providerId" : "scope",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : { }
+ } ],
+ "org.keycloak.keys.KeyProvider" : [ {
+ "id" : "6873ae62-f710-410f-adff-4529edacecd5",
+ "name" : "hmac-generated-hs512",
+ "providerId" : "hmac-generated",
+ "subComponents" : { },
+ "config" : {
+ "kid" : [ "4f547037-1b1c-4b8a-898f-32beaedbc322" ],
+ "secret" : [ "qceGbal839MtCUtk-mNlJilhXKT-x0KRIQ502tnI-Jr4pFfJMVeWa9cBBMtl_IlTt_54UY_izBsF8UGVhWiCXoA5OWgwvOO30niNHboRZ0YcD9LweLssQxfDKmYp7yla974jjSQwI3EoURv8skVpKn6S_wGwL5o3l0bwpG99KJM" ],
+ "priority" : [ "100" ],
+ "algorithm" : [ "HS512" ]
+ }
+ }, {
+ "id" : "acaf8c35-8426-4212-b476-9755e750cba8",
+ "name" : "aes-generated",
+ "providerId" : "aes-generated",
+ "subComponents" : { },
+ "config" : {
+ "kid" : [ "174f967c-38d0-48f4-84be-76342436b6a3" ],
+ "secret" : [ "PROT6xpfFNQmbuO7x-TBTA" ],
+ "priority" : [ "100" ]
+ }
+ }, {
+ "id" : "79b45bb7-9f51-4a5d-9ddb-a38193869cf8",
+ "name" : "rsa-enc-generated",
+ "providerId" : "rsa-enc-generated",
+ "subComponents" : { },
+ "config" : {
+ "privateKey" : [ "MIIEpQIBAAKCAQEAw5ebKJIOg4YccO2JtmIc4oBr18RMMsKk7mC3+jNXYjTgPlpMl8b294PTeYNG56wP2yNtqOA8jtdIfJIGM3yOunEwzoRO0u5WKy6AvGdLQvB3By5ceotVGRWqtCWlSrz/xzYIp8n9Kwj86wDOSt0PyZFIahRpRDEGmT/kcH0996VPHoLynhYRUz7ekxLApzQwCMuDkTD58YC9u0USFfvOQohc57mryQT34vqRu/RfPcl7Nv26p8T1hygeW+NNj241spLj17gKA5Nkemg4Sgvlg7yKmimMqGt9CEKKIT4Kakls2rjLMSYEOh5XacenSsLFofK7E1Tf9z0k+EDejCZ5RwIDAQABAoIBADpdLut4SeRtTGdWOlW2CTB9abDE3of3FQgczElYsKaZaKCyiVBxCpjpOV11Et9mtISLmdlesDNfgj3JxRfv/xcbV5kIWg0PGZ9hDQErQYYEA0CdUPMwSIBnurxuz1fx9dEYCpUm7Oi+kdn+L5CfTmqzc4xT8uVqS7HHIv9+H9OZdq3kkID1YwucWUWTDosjKGCu57WY96+M95UHdqQMYY4GCCgQv5OgjjzdC7VWNpffBLZHWHXh2UW9MAcE++40ryydt6LZFFxqJUpxPVwKUhmdP6YGmxlkRt7sVTsGX90zniqFN5CamxidbCO1tPjuP8fwCXcqWSwU3uW2tRhMWuECgYEA7ZDXYxwPlsRZF0ivhbqQVZFHf1jlWLNMLICy5DzwXWCVJRFVt++pQa2dgnQiRL+TfebV6qgGjK8U89GkNPNGe7wdHayWRe701/JuyKCauZc/5lfQPsG4pVZVcbIuj1hAd4gAXAytdmzQ7cBIGwTWBptJPI4DA5ct/rE9O969qh0CgYEA0sT5jJuofPQsqmnnz3KqZ7DB2fTyzmzMo6JdqfQGLwgTSapk5lWqOyNcNuNCeWYaYwlO8ZmAhzg7g7XnTE1k3iDPQhpd1gV0KlgHk549nnD47v1pDPjFlbqTjbvvB9OFYTbRwBIrAlGQKjyCAAMRcWVwxG9h4RvAdk5FheQb87MCgYEAhk57ppmHqqno4EQEj2sRDH8s168vQj1jlElSWbyl+3SN/T3Woz2ICAyaXtU/RnS0ctpdF+PUiBa3lrxvxEvBDlUkdNFMx863d5qkzSIXN1NuGdCNd91XgYnUlomwzvOKxskJwwCb1LbiS3eIjFXoliWWeviidZYzt6kGQGHGAnUCgYEAxtgoatwrn/8o6HlTxmXymDKtIDi0ncUNZ092ODHNZ6+hqr0Dxj6JhJN+mxXaj/eg61BL1ykvleKaW09Q8K6Pe/TONBn170Vj69LzCvSeQ41nfOk8o41Ls0+7h1sHToXi7u0uA5vgUaarcP121BYQ7b97HQfL+vkYoUSE2KV1LXsCgYEAp1llSgSYN7/aU0GNipu0Y9GDBIv2FEz0LERD9bdg84bpFBmT9weFACGMDiH0OXSRR22lZ1V5diqm/idRrEzs80bsIYrStGE+flwbAVIyuyyMt42Pbd65LeWNjYUWYBUVRYzOGyd+DxfjRKSXHgbE7ZdXna0k05IZNoQ2niE6rus=" ],
+ "certificate" : [ "MIICuzCCAaMCBgGTTfUQKDANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZSRUFMTV9OQU1FX1BMQUNFSE9MREVSMB4XDTI0MTEyMTA5MDAyNloXDTM0MTEyMTA5MDIwNlowITEfMB0GA1UEAwwWUkVBTE1fTkFNRV9QTEFDRUhPTERFUjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOXmyiSDoOGHHDtibZiHOKAa9fETDLCpO5gt/ozV2I04D5aTJfG9veD03mDRuesD9sjbajgPI7XSHySBjN8jrpxMM6ETtLuVisugLxnS0LwdwcuXHqLVRkVqrQlpUq8/8c2CKfJ/SsI/OsAzkrdD8mRSGoUaUQxBpk/5HB9PfelTx6C8p4WEVM+3pMSwKc0MAjLg5Ew+fGAvbtFEhX7zkKIXOe5q8kE9+L6kbv0Xz3Jezb9uqfE9YcoHlvjTY9uNbKS49e4CgOTZHpoOEoL5YO8ipopjKhrfQhCiiE+CmpJbNq4yzEmBDoeV2nHp0rCxaHyuxNU3/c9JPhA3owmeUcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAwk+tpb2RH48XnPMygvZNuex7EsnE7OV3C5VCq04qcOaFqtstvMbIrYrEIxKzu27NARi4cvHtzr1qjitmX/GpSNEPtA5/jIWjyz5IMPOh7o7J9RCfqFGEthUtfS/ec+JmaDoL15sgnoxWxXsVITLYlzPYP0EUhaJKrWxkBZ/79tfLDhKscpFXf2SRsebkBN3KdMhfVsFxnRWXOCrJbh8pqgal+GD5mdbHB9B+CJ574+tzS8p40JCoiYJp06hqlaEQ6/Pv2sLxQJAIHS3pAnA0EYPRNhFYRc6fWJb6ioSYM339Gux+8C2rFqPKZxQg5vYxPDvplxJvuylynA8NTdyVdQ==" ],
+ "priority" : [ "100" ],
+ "algorithm" : [ "RSA-OAEP" ]
+ }
+ }, {
+ "id" : "6d6fdef5-fc2a-4283-872b-78d43683405a",
+ "name" : "rsa-generated",
+ "providerId" : "rsa-generated",
+ "subComponents" : { },
+ "config" : {
+ "privateKey" : [ "MIIEpAIBAAKCAQEAw+l83QalofaA6cW7B9FPst5XWPaHpWCNwwGEDM3ZxnUo+gynw7ONGShtnXj643oqNDltTvo7e71slJTaKEgbUqu2Zcfl/B97cXV6iMUQJmSr2SXYxHYl/9tBNnLetfpntzLWgY+lkfT1peBcwk7J6K58Ym+lbEZhXf/EAHqB1gH4WTYLWhX5LEzSUTR9UoZ0o/DisarODJIGvE2RVTkRo1cKr09Md1NInWaJM9yDSOp+heFxx6wyqmrb5tylqUx5uHXo3o7RGcdttf1IVYS8jNNaQirxsbxWSJHSdwQKxt92NutcO1tv4tzDvoEeVJcKDoqs6M396k6ywSgD0UoNCQIDAQABAoIBAAD0Ri0D0N+B39oQbuGSEQO1NlLmM7FU6XVyfT4pH083V6rzUAd3/Gi+9am3fFSKgWIeIklcMD+UcJu/DdqPkowYiGh+f/RDNjEbRvmB9c4tRCXOm8h5LgsALZUiTuT8AnCCyUcTeAiTjnUixQQW3IzkxkS3q0qXtsNKcTeMLgDo1CaFDPCQR5HAA6FG2w0Xb3MCa9SOGgRzauO13zoO1B9U4+HGvhVF5k+e+evuAdzHLapvWkDQRkNuXb/ScJAEUzRJ94yPFHgg1Vg/Gg9GVVvMGQB5yX2EeaLMd3N8qhHl2JN/b4vmOQZzpAxWY1GT4Yd0WE0O+NovaMEvDdRVFgECgYEA+8hweFvkTBaBau228yw6DeBNXvDjJzWoPEVznfSWnozTYR8IV8mgOaUsUHE6EmMaDVp0YUJ5JQpBZQ3nkUOO9QU8+i3zq1MNP7aKHiQGpX7O6F3Milq81YP6xa+0HmdvW5TRIiX95KMj2vBrsImXkLR/tUUBW+DNg7iX8c1AjbECgYEAxzF+JeivUup/3vmOmZcmwTHHF4BacNKN7c9scnimebJA7LfgaXAeijijfaXRw/9JB0tUxfYE9NbVwCkBmnKAjIxtrIDxlMRmOz9AjakoP7EZnlgv6iSo7H+JDhlYTHu8ZUPG8XlR5SyU5kGLHkL6anx4PHL6lEbjjsxnzJKzktkCgYEAoqjsWCVtiOZlN5JZRiJFYx+MfJB8/6C/jiiEOACCqe1qxezJdAVzOKqHxXRQwv45H3VXiFnsb8x/UOy5tHQD0DFRIoM7T2x5O7cO5cf6b0JMI3wtnxhdtEbuZHZNk/LY0z6CGWCX9PScPl5iBAvv2fFyK8ZnyVajDrzblMA4OxECgYA1FhGilMK0/F4b1LKWaFwhvNxsfP6ddt/wcwlZ8KGdaU44SED8mK7q83FO+TRQYebalM8A+zIS9nZ9AfC1crKjwoEwKiU4GqeMPq07k8twPgiv1Jzgb+i9LrgeE88egxOQgWGx1T1oMFt2ih1DcWI/ovCAW7xAbCwVUJCRSr+k8QKBgQCnxzePHwZNhwdzzQbp7/mTVryd96A23iSla5DTqTf5mwrKz3zDpfIfm4LDimyCmEm3zjF/pd5t5Cdkt+yrqyWnwTlmJ0Ln2wDVz1ZHfJQ3V49yp9rkvStzDkfc/3iA+65nBzpkB/bXKaxKGjcMWcTYVjlTABqwkucZPzBSqELsxQ==" ],
+ "certificate" : [ "MIICuzCCAaMCBgGTTfUQazANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZSRUFMTV9OQU1FX1BMQUNFSE9MREVSMB4XDTI0MTEyMTA5MDAyNloXDTM0MTEyMTA5MDIwNlowITEfMB0GA1UEAwwWUkVBTE1fTkFNRV9QTEFDRUhPTERFUjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMPpfN0GpaH2gOnFuwfRT7LeV1j2h6VgjcMBhAzN2cZ1KPoMp8OzjRkobZ14+uN6KjQ5bU76O3u9bJSU2ihIG1KrtmXH5fwfe3F1eojFECZkq9kl2MR2Jf/bQTZy3rX6Z7cy1oGPpZH09aXgXMJOyeiufGJvpWxGYV3/xAB6gdYB+Fk2C1oV+SxM0lE0fVKGdKPw4rGqzgySBrxNkVU5EaNXCq9PTHdTSJ1miTPcg0jqfoXhccesMqpq2+bcpalMebh16N6O0RnHbbX9SFWEvIzTWkIq8bG8VkiR0ncECsbfdjbrXDtbb+Lcw76BHlSXCg6KrOjN/epOssEoA9FKDQkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAs6EEnro283f2aTTNlGYwmLThjdTynZ0f8EyTyjweJa8uzUF6zWvpAMgKgM2GVa32UpCMxydsfkn0ipsDpav1f426TBTD9wPSAtnU8nkZVX7AWtWtI6I0G3S/udKirZ2lxETSSmE5ifaO9SF1h/dEVeSJ1tr/C/YEE8ATceKgtJ7Qt8XvAgcvQuR7LCGu1HuHs2ohAvv3hjeD5Oj3HMsnLCHGHmiDW1iSxi09vkvBEDW8Hgq5/NFS/30+lnLAcA8Wx9+6zKyHWJW+f8pi6EiZgi3re8QqgJcFv/fkJjQMG9bPznfZuA+c8irLyWw6A5TLa618IqcgRZvzUyDasH4GvQ==" ],
+ "priority" : [ "100" ]
+ }
+ } ]
+ },
+ "internationalizationEnabled" : false,
+ "supportedLocales" : [ ],
+ "authenticationFlows" : [ {
+ "id" : "820f56e1-92f9-489a-8d5b-435c3090d565",
+ "alias" : "Account verification options",
+ "description" : "Method with which to verity the existing account",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "idp-email-verification",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Verify Existing Account by Re-authentication",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "485f4929-8cd5-4823-ab43-46632ff328f1",
+ "alias" : "Browser - Conditional OTP",
+ "description" : "Flow to determine if the OTP is required for the authentication",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "conditional-user-configured",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "auth-otp-form",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "7cd25178-93e4-40a1-85a3-a7eedd1eee58",
+ "alias" : "Browser - Conditional Organization",
+ "description" : "Flow to determine if the organization identity-first login is to be used",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "conditional-user-configured",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "organization",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "13859544-1f4e-4d3a-9c59-160d72f1ef09",
+ "alias" : "Direct Grant - Conditional OTP",
+ "description" : "Flow to determine if the OTP is required for the authentication",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "conditional-user-configured",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "direct-grant-validate-otp",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "95b03f52-3e9a-4745-9f2d-fa92024f892a",
+ "alias" : "First Broker Login - Conditional Organization",
+ "description" : "Flow to determine if the authenticator that adds organization members is to be used",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "conditional-user-configured",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "idp-add-organization-member",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "e0b0819f-f839-4ac3-93bc-a6944d789c6b",
+ "alias" : "First broker login - Conditional OTP",
+ "description" : "Flow to determine if the OTP is required for the authentication",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "conditional-user-configured",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "auth-otp-form",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "a39f72d5-7336-48bf-9abd-c6247d3c5188",
+ "alias" : "Handle Existing Account",
+ "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "idp-confirm-link",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Account verification options",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "d0ebe092-0fd9-4884-9df2-0fc19560cf0a",
+ "alias" : "Organization",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticatorFlow" : true,
+ "requirement" : "CONDITIONAL",
+ "priority" : 10,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Browser - Conditional Organization",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "7b9d4855-89f8-4df6-beda-bfb035f9a244",
+ "alias" : "Reset - Conditional OTP",
+ "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "conditional-user-configured",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "reset-otp",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "df1575c6-b9cd-4342-8c85-c6376853866d",
+ "alias" : "User creation or linking",
+ "description" : "Flow for the existing/non-existing user alternatives",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticatorConfig" : "create unique user config",
+ "authenticator" : "idp-create-user-if-unique",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Handle Existing Account",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "10a02bfc-f238-4b94-abbd-7706c2f21b70",
+ "alias" : "Verify Existing Account by Re-authentication",
+ "description" : "Reauthentication of existing account",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "idp-username-password-form",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "CONDITIONAL",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "First broker login - Conditional OTP",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "63965b58-1b62-4f3a-9fd3-7e3e3c4c3eed",
+ "alias" : "browser",
+ "description" : "browser based authentication",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "auth-cookie",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "auth-spnego",
+ "authenticatorFlow" : false,
+ "requirement" : "DISABLED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "identity-provider-redirector",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 25,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 26,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Organization",
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 30,
+ "autheticatorFlow" : true,
+ "flowAlias" : "forms",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "618c8052-b998-4181-85f3-6e171a8ad356",
+ "alias" : "clients",
+ "description" : "Base authentication for clients",
+ "providerId" : "client-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "client-secret",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "client-jwt",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "client-secret-jwt",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 30,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "client-x509",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 40,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "ca3e691a-2326-450b-93d0-eb9929fc3745",
+ "alias" : "direct grant",
+ "description" : "OpenID Connect Resource Owner Grant",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "direct-grant-validate-username",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "direct-grant-validate-password",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "CONDITIONAL",
+ "priority" : 30,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Direct Grant - Conditional OTP",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "e8c2f7fe-c611-4ef9-a062-8d6c3388f797",
+ "alias" : "docker auth",
+ "description" : "Used by Docker clients to authenticate against the IDP",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "docker-http-basic-authenticator",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "178a91fc-9bb6-43c2-88cc-5fd73afe2d75",
+ "alias" : "first broker login",
+ "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticatorConfig" : "review profile config",
+ "authenticator" : "idp-review-profile",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "User creation or linking",
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "CONDITIONAL",
+ "priority" : 50,
+ "autheticatorFlow" : true,
+ "flowAlias" : "First Broker Login - Conditional Organization",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "4c38d67f-c298-4b46-aec8-df00f853e64a",
+ "alias" : "forms",
+ "description" : "Username, password, otp and other auth forms.",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "auth-username-password-form",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "CONDITIONAL",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Browser - Conditional OTP",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "ee4ae8cd-0770-44a0-89c5-de1bb96971df",
+ "alias" : "registration",
+ "description" : "registration flow",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "registration-page-form",
+ "authenticatorFlow" : true,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : true,
+ "flowAlias" : "registration form",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "9af610f3-08e4-4a3a-a2f2-a85c9cc65f88",
+ "alias" : "registration form",
+ "description" : "registration form",
+ "providerId" : "form-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "registration-user-creation",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "registration-password-action",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 50,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "registration-recaptcha-action",
+ "authenticatorFlow" : false,
+ "requirement" : "DISABLED",
+ "priority" : 60,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "registration-terms-and-conditions",
+ "authenticatorFlow" : false,
+ "requirement" : "DISABLED",
+ "priority" : 70,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "def02675-afb8-479b-9756-b6399c49a616",
+ "alias" : "reset credentials",
+ "description" : "Reset credentials for a user if they forgot their password or something",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "reset-credentials-choose-user",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "reset-credential-email",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "reset-password",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 30,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "CONDITIONAL",
+ "priority" : 40,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Reset - Conditional OTP",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "4da59173-6c48-4f89-a8f1-b9ffe3952641",
+ "alias" : "saml ecp",
+ "description" : "SAML ECP Profile Authentication Flow",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "http-basic-authenticator",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ } ],
+ "authenticatorConfig" : [ {
+ "id" : "5aab6c05-0143-49e2-a8a7-b886685e00b9",
+ "alias" : "create unique user config",
+ "config" : {
+ "require.password.update.after.registration" : "false"
+ }
+ }, {
+ "id" : "c00631ca-8122-41e7-bffc-6034063cc7b1",
+ "alias" : "review profile config",
+ "config" : {
+ "update.profile.on.first.login" : "missing"
+ }
+ } ],
+ "requiredActions" : [ {
+ "alias" : "CONFIGURE_TOTP",
+ "name" : "Configure OTP",
+ "providerId" : "CONFIGURE_TOTP",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 10,
+ "config" : { }
+ }, {
+ "alias" : "TERMS_AND_CONDITIONS",
+ "name" : "Terms and Conditions",
+ "providerId" : "TERMS_AND_CONDITIONS",
+ "enabled" : false,
+ "defaultAction" : false,
+ "priority" : 20,
+ "config" : { }
+ }, {
+ "alias" : "UPDATE_PASSWORD",
+ "name" : "Update Password",
+ "providerId" : "UPDATE_PASSWORD",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 30,
+ "config" : { }
+ }, {
+ "alias" : "UPDATE_PROFILE",
+ "name" : "Update Profile",
+ "providerId" : "UPDATE_PROFILE",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 40,
+ "config" : { }
+ }, {
+ "alias" : "VERIFY_EMAIL",
+ "name" : "Verify Email",
+ "providerId" : "VERIFY_EMAIL",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 50,
+ "config" : { }
+ }, {
+ "alias" : "delete_account",
+ "name" : "Delete Account",
+ "providerId" : "delete_account",
+ "enabled" : false,
+ "defaultAction" : false,
+ "priority" : 60,
+ "config" : { }
+ }, {
+ "alias" : "CONFIGURE_RECOVERY_AUTHN_CODES",
+ "name" : "Recovery Authentication Codes",
+ "providerId" : "CONFIGURE_RECOVERY_AUTHN_CODES",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 70,
+ "config" : { }
+ }, {
+ "alias" : "UPDATE_EMAIL",
+ "name" : "Update Email",
+ "providerId" : "UPDATE_EMAIL",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 70,
+ "config" : { }
+ }, {
+ "alias" : "webauthn-register",
+ "name" : "Webauthn Register",
+ "providerId" : "webauthn-register",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 70,
+ "config" : { }
+ }, {
+ "alias" : "webauthn-register-passwordless",
+ "name" : "Webauthn Register Passwordless",
+ "providerId" : "webauthn-register-passwordless",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 80,
+ "config" : { }
+ }, {
+ "alias" : "VERIFY_PROFILE",
+ "name" : "Verify Profile",
+ "providerId" : "VERIFY_PROFILE",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 90,
+ "config" : { }
+ }, {
+ "alias" : "delete_credential",
+ "name" : "Delete Credential",
+ "providerId" : "delete_credential",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 100,
+ "config" : { }
+ }, {
+ "alias" : "update_user_locale",
+ "name" : "Update User Locale",
+ "providerId" : "update_user_locale",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 1000,
+ "config" : { }
+ } ],
+ "browserFlow" : "browser",
+ "registrationFlow" : "registration",
+ "directGrantFlow" : "direct grant",
+ "resetCredentialsFlow" : "reset credentials",
+ "clientAuthenticationFlow" : "clients",
+ "dockerAuthenticationFlow" : "docker auth",
+ "firstBrokerLoginFlow" : "first broker login",
+ "attributes" : {
+ "cibaBackchannelTokenDeliveryMode" : "poll",
+ "cibaAuthRequestedUserHint" : "login_hint",
+ "clientOfflineSessionMaxLifespan" : "0",
+ "oauth2DevicePollingInterval" : "5",
+ "clientSessionIdleTimeout" : "0",
+ "clientOfflineSessionIdleTimeout" : "0",
+ "cibaInterval" : "5",
+ "realmReusableOtpCode" : "false",
+ "cibaExpiresIn" : "120",
+ "oauth2DeviceCodeLifespan" : "600",
+ "parRequestUriLifespan" : "60",
+ "clientSessionMaxLifespan" : "0",
+ "organizationsEnabled" : "false"
+ },
+ "keycloakVersion" : "26.0.5",
+ "userManagedAccessAllowed" : false,
+ "organizationsEnabled" : false,
+ "clientProfiles" : {
+ "profiles" : [ ]
+ },
+ "clientPolicies" : {
+ "policies" : [ ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/adorsys/keycloak/config/configuration/NormalizeTestConfiguration.java b/src/test/java/de/adorsys/keycloak/config/configuration/NormalizeTestConfiguration.java
new file mode 100644
index 000000000..a27f1e142
--- /dev/null
+++ b/src/test/java/de/adorsys/keycloak/config/configuration/NormalizeTestConfiguration.java
@@ -0,0 +1,35 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2021 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.configuration;
+
+import de.adorsys.keycloak.config.properties.NormalizationConfigProperties;
+import de.adorsys.keycloak.config.properties.NormalizationKeycloakConfigProperties;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages = {"de.adorsys.keycloak.config"})
+@EnableConfigurationProperties({NormalizationKeycloakConfigProperties.class, NormalizationConfigProperties.class})
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "NORMALIZE")
+public class NormalizeTestConfiguration {
+}
diff --git a/src/test/java/de/adorsys/keycloak/config/configuration/TestConfiguration.java b/src/test/java/de/adorsys/keycloak/config/configuration/TestConfiguration.java
index 27685c07a..258f4b868 100644
--- a/src/test/java/de/adorsys/keycloak/config/configuration/TestConfiguration.java
+++ b/src/test/java/de/adorsys/keycloak/config/configuration/TestConfiguration.java
@@ -22,6 +22,7 @@
import de.adorsys.keycloak.config.properties.ImportConfigProperties;
import de.adorsys.keycloak.config.properties.KeycloakConfigProperties;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@@ -29,6 +30,7 @@
@Configuration
@ComponentScan(basePackages = {"de.adorsys.keycloak.config"})
@EnableConfigurationProperties({KeycloakConfigProperties.class, ImportConfigProperties.class})
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class TestConfiguration {
}
diff --git a/src/test/java/de/adorsys/keycloak/config/normalize/AbstractNormalizeTest.java b/src/test/java/de/adorsys/keycloak/config/normalize/AbstractNormalizeTest.java
new file mode 100644
index 000000000..be0412dee
--- /dev/null
+++ b/src/test/java/de/adorsys/keycloak/config/normalize/AbstractNormalizeTest.java
@@ -0,0 +1,47 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2021 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package de.adorsys.keycloak.config.normalize;
+
+import de.adorsys.keycloak.config.configuration.NormalizeTestConfiguration;
+import de.adorsys.keycloak.config.extensions.GithubActionsExtension;
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;
+import org.springframework.boot.test.system.OutputCaptureExtension;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+@ExtendWith(SpringExtension.class)
+@ExtendWith(GithubActionsExtension.class)
+@ExtendWith(OutputCaptureExtension.class)
+@ContextConfiguration(
+ classes = {NormalizeTestConfiguration.class},
+ initializers = {ConfigDataApplicationContextInitializer.class}
+)
+@ActiveProfiles("normalize-IT")
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+@TestClassOrder(ClassOrderer.OrderAnnotation.class)
+@Timeout(value = 30, unit = SECONDS)
+public abstract class AbstractNormalizeTest {
+}
diff --git a/src/test/java/de/adorsys/keycloak/config/service/normalize/AuthFlowNormalizationServiceConfigIT.java b/src/test/java/de/adorsys/keycloak/config/service/normalize/AuthFlowNormalizationServiceConfigIT.java
new file mode 100644
index 000000000..e84a02747
--- /dev/null
+++ b/src/test/java/de/adorsys/keycloak/config/service/normalize/AuthFlowNormalizationServiceConfigIT.java
@@ -0,0 +1,100 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2021 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+package de.adorsys.keycloak.config.service.normalize;
+
+import de.adorsys.keycloak.config.normalize.AbstractNormalizeTest;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
+import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.system.CapturedOutput;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+class AuthFlowNormalizationServiceConfigIT extends AbstractNormalizeTest {
+
+ @Autowired
+ AuthFlowNormalizationService service;
+
+ @Test
+ public void testNormalizeAuthConfigsWithEmptyListsIsNull() {
+ var resultingAuthConfig = service.normalizeAuthConfig(new ArrayList<>(), new ArrayList<>());
+ Assertions.assertThat(resultingAuthConfig).isNull();
+ }
+
+ @Test
+ public void testNormalizeAuthConfigsAreRemovedWithoutAliasReference(CapturedOutput output) {
+ AuthenticatorConfigRepresentation authenticatorConfigRepresentation = new AuthenticatorConfigRepresentation();
+ authenticatorConfigRepresentation.setAlias("config2");
+
+ AuthenticationFlowRepresentation authenticationFlowRepresentation = new AuthenticationFlowRepresentation();
+
+ AuthenticationExecutionExportRepresentation authenticationExecutionExportRepresentation = new AuthenticationExecutionExportRepresentation();
+ authenticationExecutionExportRepresentation.setAuthenticatorConfig("config1");
+ authenticationFlowRepresentation.setAuthenticationExecutions(List.of(authenticationExecutionExportRepresentation));
+
+ var resultingAuthConfig = service.normalizeAuthConfig(List.of(authenticatorConfigRepresentation), List.of(authenticationFlowRepresentation));
+
+ Assertions.assertThat(resultingAuthConfig).isNull();
+ Assertions.assertThat(output.getOut()).contains("Some authenticator configs are unused.");
+ }
+
+ @Test
+ public void testNormalizeAuthConfigsRemainWithAliasReference() {
+ AuthenticatorConfigRepresentation authenticatorConfigRepresentation = new AuthenticatorConfigRepresentation();
+ authenticatorConfigRepresentation.setAlias("config1");
+
+ AuthenticationFlowRepresentation authenticationFlowRepresentation = new AuthenticationFlowRepresentation();
+
+ AuthenticationExecutionExportRepresentation authenticationExecutionExportRepresentation = new AuthenticationExecutionExportRepresentation();
+ authenticationExecutionExportRepresentation.setAuthenticatorConfig("config1");
+ authenticationFlowRepresentation.setAuthenticationExecutions(List.of(authenticationExecutionExportRepresentation));
+
+ var resultingAuthConfig = service.normalizeAuthConfig(List.of(authenticatorConfigRepresentation), List.of(authenticationFlowRepresentation));
+
+ Assertions.assertThat(resultingAuthConfig).containsExactlyInAnyOrder(authenticatorConfigRepresentation);
+ }
+
+ @Test
+ public void testNormalizeAuthConfigsCheckedForDuplicates(CapturedOutput output) {
+ AuthenticatorConfigRepresentation authenticatorConfigRepresentation1 = new AuthenticatorConfigRepresentation();
+ authenticatorConfigRepresentation1.setId(UUID.randomUUID().toString());
+ authenticatorConfigRepresentation1.setAlias("config1");
+
+ AuthenticatorConfigRepresentation authenticatorConfigRepresentation2 = new AuthenticatorConfigRepresentation();
+ authenticatorConfigRepresentation2.setId(UUID.randomUUID().toString());
+ authenticatorConfigRepresentation2.setAlias("config1");
+
+ AuthenticationFlowRepresentation authenticationFlowRepresentation = new AuthenticationFlowRepresentation();
+
+ AuthenticationExecutionExportRepresentation authenticationExecutionExportRepresentation = new AuthenticationExecutionExportRepresentation();
+ authenticationExecutionExportRepresentation.setAuthenticatorConfig("config1");
+ authenticationFlowRepresentation.setAuthenticationExecutions(List.of(authenticationExecutionExportRepresentation));
+
+ var resultingAuthConfig = service.normalizeAuthConfig(List.of(authenticatorConfigRepresentation1, authenticatorConfigRepresentation2), List.of(authenticationFlowRepresentation));
+
+ Assertions.assertThat(resultingAuthConfig).containsExactlyInAnyOrder(authenticatorConfigRepresentation1, authenticatorConfigRepresentation2);
+ Assertions.assertThat(output.getOut()).contains("The following authenticator configs are duplicates: [config1]");
+ }
+}
diff --git a/src/test/java/de/adorsys/keycloak/config/service/normalize/AuthFlowNormalizationServiceFlowIT.java b/src/test/java/de/adorsys/keycloak/config/service/normalize/AuthFlowNormalizationServiceFlowIT.java
new file mode 100644
index 000000000..9cf67c2dd
--- /dev/null
+++ b/src/test/java/de/adorsys/keycloak/config/service/normalize/AuthFlowNormalizationServiceFlowIT.java
@@ -0,0 +1,72 @@
+/*-
+ * ---license-start
+ * keycloak-config-cli
+ * ---
+ * Copyright (C) 2017 - 2021 adorsys GmbH & Co. KG @ https://adorsys.com
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+package de.adorsys.keycloak.config.service.normalize;
+
+import de.adorsys.keycloak.config.normalize.AbstractNormalizeTest;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.system.CapturedOutput;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class AuthFlowNormalizationServiceFlowIT extends AbstractNormalizeTest {
+
+ @Autowired
+ AuthFlowNormalizationService service;
+
+
+ @Test
+ public void testNormalizeAuthFlows() {
+ var resultingAuthFlows = service.normalizeAuthFlows(new ArrayList<>(), new ArrayList<>());
+ Assertions.assertThat(resultingAuthFlows).isNull();
+ }
+
+ @Test
+ public void testNormalizeAuthFlowsIgnoreBuiltInTrue() {
+ AuthenticationFlowRepresentation authenticationFlowRepresentation = new AuthenticationFlowRepresentation();
+ authenticationFlowRepresentation.setBuiltIn(true);
+
+ AuthenticationFlowRepresentation authenticationFlowRepresentationBaseline = new AuthenticationFlowRepresentation();
+ authenticationFlowRepresentationBaseline.setBuiltIn(true);
+
+ var resultingAuthFlows = service.normalizeAuthFlows(List.of(authenticationFlowRepresentation), List.of(authenticationFlowRepresentationBaseline));
+
+ Assertions.assertThat(resultingAuthFlows).isNull();
+ }
+
+ @Test
+ public void testNormalizeAuthFlowsIgnoreBuiltInTrueButBaselineHasEntryCreatesRecreationWarning(CapturedOutput output) {
+ AuthenticationFlowRepresentation authenticationFlowRepresentation = new AuthenticationFlowRepresentation();
+ authenticationFlowRepresentation.setBuiltIn(true);
+
+ AuthenticationFlowRepresentation authenticationFlowRepresentationBaseline = new AuthenticationFlowRepresentation();
+ authenticationFlowRepresentationBaseline.setBuiltIn(false);
+ authenticationFlowRepresentationBaseline.setAlias("flow1");
+
+ var resultingAuthFlows = service.normalizeAuthFlows(List.of(authenticationFlowRepresentation), List.of(authenticationFlowRepresentationBaseline));
+
+ Assertions.assertThat(resultingAuthFlows).isNull();
+ Assertions.assertThat(output.getOut()).contains("Default realm authentication flow 'flow1' was deleted in exported realm. It may be reintroduced during import");
+
+ }
+}
diff --git a/src/test/java/de/adorsys/keycloak/config/test/util/KeycloakAuthentication.java b/src/test/java/de/adorsys/keycloak/config/test/util/KeycloakAuthentication.java
index fc51a9c29..0fd695d1b 100644
--- a/src/test/java/de/adorsys/keycloak/config/test/util/KeycloakAuthentication.java
+++ b/src/test/java/de/adorsys/keycloak/config/test/util/KeycloakAuthentication.java
@@ -24,9 +24,11 @@
import org.keycloak.admin.client.Keycloak;
import org.keycloak.representations.AccessTokenResponse;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class KeycloakAuthentication {
private final KeycloakConfigProperties keycloakConfigProperties;
diff --git a/src/test/java/de/adorsys/keycloak/config/test/util/KeycloakRepository.java b/src/test/java/de/adorsys/keycloak/config/test/util/KeycloakRepository.java
index 4e4c15260..4e5da67fa 100644
--- a/src/test/java/de/adorsys/keycloak/config/test/util/KeycloakRepository.java
+++ b/src/test/java/de/adorsys/keycloak/config/test/util/KeycloakRepository.java
@@ -24,6 +24,7 @@
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.*;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.util.List;
@@ -34,6 +35,7 @@
import static org.hamcrest.Matchers.hasSize;
@Component
+@ConditionalOnProperty(prefix = "run", name = "operation", havingValue = "IMPORT", matchIfMissing = true)
public class KeycloakRepository {
private final KeycloakProvider keycloakProvider;
diff --git a/src/test/resources/application-normalize-IT.properties b/src/test/resources/application-normalize-IT.properties
new file mode 100644
index 000000000..77a36297e
--- /dev/null
+++ b/src/test/resources/application-normalize-IT.properties
@@ -0,0 +1,3 @@
+run.operation=normalize
+normalization.files.input-locations=default
+normalization.files.output-directory=default-output
diff --git a/src/test/resources/import-files/exported-realm/25.0.1/master-realm.json b/src/test/resources/import-files/exported-realm/25.0.1/master-realm.json
index 0b3fba793..6856d9e6c 100644
--- a/src/test/resources/import-files/exported-realm/25.0.1/master-realm.json
+++ b/src/test/resources/import-files/exported-realm/25.0.1/master-realm.json
@@ -1,5 +1,5 @@
{
- "id" : "758ff4fc-bf09-403b-adbe-c9a56cadd5d3",
+ "id" : "6219f172-5cbc-40f1-99fc-74218bbb2642",
"realm" : "master",
"displayName" : "Keycloak",
"displayNameHtml" : "Keycloak
",
@@ -48,56 +48,56 @@
"failureFactor" : 30,
"roles" : {
"realm" : [ {
- "id" : "53a94a55-01b7-4ac3-97a1-1df924dfcf05",
- "name" : "admin",
- "description" : "${role_admin}",
- "composite" : true,
- "composites" : {
- "realm" : [ "create-realm" ],
- "client" : {
- "master-realm" : [ "view-identity-providers", "manage-realm", "view-authorization", "query-realms", "manage-users", "query-groups", "manage-events", "impersonation", "create-client", "view-users", "manage-authorization", "manage-clients", "manage-identity-providers", "view-events", "query-clients", "view-realm", "query-users", "view-clients" ]
- }
- },
+ "id" : "6adf69e5-3f69-4ae0-b2f9-6bf3663f10df",
+ "name" : "create-realm",
+ "description" : "${role_create-realm}",
+ "composite" : false,
"clientRole" : false,
- "containerId" : "758ff4fc-bf09-403b-adbe-c9a56cadd5d3",
+ "containerId" : "6219f172-5cbc-40f1-99fc-74218bbb2642",
"attributes" : { }
}, {
- "id" : "1d93addd-604f-4388-bff2-48849ce0317c",
- "name" : "default-roles-master",
- "description" : "${role_default-roles}",
+ "id" : "bb03f721-bd79-4a61-97a5-963ed89fffc2",
+ "name" : "admin",
+ "description" : "${role_admin}",
"composite" : true,
"composites" : {
- "realm" : [ "offline_access", "uma_authorization" ],
+ "realm" : [ "create-realm" ],
"client" : {
- "account" : [ "manage-account", "view-profile" ]
+ "master-realm" : [ "view-realm", "query-groups", "view-identity-providers", "view-users", "manage-clients", "impersonation", "view-events", "view-authorization", "create-client", "manage-identity-providers", "query-users", "manage-events", "manage-realm", "view-clients", "query-clients", "manage-users", "query-realms", "manage-authorization" ]
}
},
"clientRole" : false,
- "containerId" : "758ff4fc-bf09-403b-adbe-c9a56cadd5d3",
+ "containerId" : "6219f172-5cbc-40f1-99fc-74218bbb2642",
"attributes" : { }
}, {
- "id" : "9b065c78-db9e-4183-b94c-32e4e938e753",
+ "id" : "a679e5c1-976e-48bf-9082-02d743a9e589",
"name" : "uma_authorization",
"description" : "${role_uma_authorization}",
"composite" : false,
"clientRole" : false,
- "containerId" : "758ff4fc-bf09-403b-adbe-c9a56cadd5d3",
+ "containerId" : "6219f172-5cbc-40f1-99fc-74218bbb2642",
"attributes" : { }
}, {
- "id" : "98701e4d-2cb1-4916-b6c1-3a1e5fa8b98f",
- "name" : "create-realm",
- "description" : "${role_create-realm}",
+ "id" : "ac87814d-ff14-4e9d-8868-b266c437e6d6",
+ "name" : "offline_access",
+ "description" : "${role_offline-access}",
"composite" : false,
"clientRole" : false,
- "containerId" : "758ff4fc-bf09-403b-adbe-c9a56cadd5d3",
+ "containerId" : "6219f172-5cbc-40f1-99fc-74218bbb2642",
"attributes" : { }
}, {
- "id" : "868a6403-4176-49bf-a0e7-57f97f738a93",
- "name" : "offline_access",
- "description" : "${role_offline-access}",
- "composite" : false,
+ "id" : "0de3d9a9-ce18-4638-806f-a96e61e93e62",
+ "name" : "default-roles-master",
+ "description" : "${role_default-roles}",
+ "composite" : true,
+ "composites" : {
+ "realm" : [ "offline_access", "uma_authorization" ],
+ "client" : {
+ "account" : [ "view-profile", "manage-account" ]
+ }
+ },
"clientRole" : false,
- "containerId" : "758ff4fc-bf09-403b-adbe-c9a56cadd5d3",
+ "containerId" : "6219f172-5cbc-40f1-99fc-74218bbb2642",
"attributes" : { }
} ],
"client" : {
@@ -105,254 +105,254 @@
"admin-cli" : [ ],
"account-console" : [ ],
"broker" : [ {
- "id" : "a6139113-e9c8-4343-9de3-3a46d4c4efe7",
+ "id" : "79f6152f-2a01-49de-9bda-217c8dc37ed9",
"name" : "read-token",
"description" : "${role_read-token}",
"composite" : false,
"clientRole" : true,
- "containerId" : "6b259285-42b1-430f-b619-b83ca1b86e14",
+ "containerId" : "7000b14a-6262-498a-a2f5-244e4678377b",
"attributes" : { }
} ],
"master-realm" : [ {
- "id" : "a163010b-6b99-4f2e-abe3-7f36ba5f5216",
- "name" : "manage-realm",
- "description" : "${role_manage-realm}",
+ "id" : "c392c688-47d7-437b-adec-22136507b23f",
+ "name" : "view-realm",
+ "description" : "${role_view-realm}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "2c6efea3-2979-45e8-b10a-b95ececa0a25",
- "name" : "view-identity-providers",
- "description" : "${role_view-identity-providers}",
+ "id" : "67373ba8-2fef-486f-a073-f70fe6ff2d40",
+ "name" : "query-groups",
+ "description" : "${role_query-groups}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "e978f2e8-76ed-45cf-a23e-66ee5cbc95b8",
- "name" : "view-authorization",
- "description" : "${role_view-authorization}",
+ "id" : "ceb4d197-4bcc-47e8-8a01-23cdbf866d99",
+ "name" : "manage-clients",
+ "description" : "${role_manage-clients}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "b548358b-4380-4e03-bb26-06b3411b19ad",
- "name" : "query-realms",
- "description" : "${role_query-realms}",
+ "id" : "1cbe7eae-2531-4886-8e15-4ebcb64f4d6a",
+ "name" : "view-identity-providers",
+ "description" : "${role_view-identity-providers}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "9cb299ae-2994-4d56-afab-1de48dcceb40",
- "name" : "manage-users",
- "description" : "${role_manage-users}",
- "composite" : false,
+ "id" : "7f84085d-61a9-48ea-9413-f1a6cf624de3",
+ "name" : "view-users",
+ "description" : "${role_view-users}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "master-realm" : [ "query-users", "query-groups" ]
+ }
+ },
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "97eb77cd-1b31-4c65-a259-e223625d3f57",
- "name" : "query-groups",
- "description" : "${role_query-groups}",
+ "id" : "90844634-3048-4978-9627-850fd860cff9",
+ "name" : "impersonation",
+ "description" : "${role_impersonation}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "87209a50-c857-4c25-927c-e99894473644",
- "name" : "manage-events",
- "description" : "${role_manage-events}",
+ "id" : "c3f0eca1-d6f3-444e-af5f-f5d06aae2109",
+ "name" : "view-events",
+ "description" : "${role_view-events}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "2cc052ac-aa7f-4b7f-a214-90970e1796fd",
- "name" : "impersonation",
- "description" : "${role_impersonation}",
+ "id" : "25add48d-8b05-4e38-a186-1b87bb6e41d8",
+ "name" : "view-authorization",
+ "description" : "${role_view-authorization}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "3346327d-b28e-4953-8221-f2df72921c57",
+ "id" : "f4982c2e-16eb-4952-a89d-baedccef43ee",
"name" : "create-client",
"description" : "${role_create-client}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "c1acb6df-0a73-4c25-a60c-ef3056402f0c",
- "name" : "view-users",
- "description" : "${role_view-users}",
- "composite" : true,
- "composites" : {
- "client" : {
- "master-realm" : [ "query-groups", "query-users" ]
- }
- },
+ "id" : "f86aba84-f00c-4e7f-b61a-69b904407054",
+ "name" : "manage-identity-providers",
+ "description" : "${role_manage-identity-providers}",
+ "composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "63b51825-4b31-4202-aa8d-3bcff3a32e81",
- "name" : "manage-authorization",
- "description" : "${role_manage-authorization}",
+ "id" : "af9bd51e-4ea8-4f76-a6e4-24a3c185199a",
+ "name" : "query-users",
+ "description" : "${role_query-users}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "972d72c4-1f32-4820-88c8-cecca886f210",
- "name" : "manage-clients",
- "description" : "${role_manage-clients}",
+ "id" : "f5f10511-8bb2-42c0-9c29-e65704de7975",
+ "name" : "manage-events",
+ "description" : "${role_manage-events}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "a859851a-ad17-44f8-a166-976a7f747dc9",
- "name" : "manage-identity-providers",
- "description" : "${role_manage-identity-providers}",
+ "id" : "639eb9ed-6a64-4c39-9fbb-62eab53f8757",
+ "name" : "manage-realm",
+ "description" : "${role_manage-realm}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "ae843368-1257-444d-8bd9-5e7bca083c9c",
- "name" : "view-events",
- "description" : "${role_view-events}",
- "composite" : false,
+ "id" : "6528f9b3-441b-4804-a1ce-e49800180828",
+ "name" : "view-clients",
+ "description" : "${role_view-clients}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "master-realm" : [ "query-clients" ]
+ }
+ },
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "54aeb96f-1659-44d0-b04a-8b6b4a366b86",
+ "id" : "8806c16d-f477-4961-822f-84a85943d1a5",
"name" : "query-clients",
"description" : "${role_query-clients}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "4005abb7-7e93-4d21-abd6-2831ac384d38",
- "name" : "view-realm",
- "description" : "${role_view-realm}",
+ "id" : "d49309b7-e9db-44d1-bb2a-9400749b2cba",
+ "name" : "manage-users",
+ "description" : "${role_manage-users}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "119041e5-873f-4e61-a507-8e34e4a29c83",
- "name" : "query-users",
- "description" : "${role_query-users}",
+ "id" : "b248d6b9-88a9-446c-b342-cffa0c0e1c68",
+ "name" : "manage-authorization",
+ "description" : "${role_manage-authorization}",
"composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
}, {
- "id" : "6582bf22-fb94-4c3d-9269-3ba600b6a3a1",
- "name" : "view-clients",
- "description" : "${role_view-clients}",
- "composite" : true,
- "composites" : {
- "client" : {
- "master-realm" : [ "query-clients" ]
- }
- },
+ "id" : "649be7d5-0867-4239-823e-1a52009723a0",
+ "name" : "query-realms",
+ "description" : "${role_query-realms}",
+ "composite" : false,
"clientRole" : true,
- "containerId" : "01702696-84f2-4815-9385-493495f5542e",
+ "containerId" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"attributes" : { }
} ],
"account" : [ {
- "id" : "5319ddd7-6971-4022-b43a-30ee6029d25d",
- "name" : "manage-consent",
- "description" : "${role_manage-consent}",
+ "id" : "00f89d17-5a26-43b4-978d-0bdf53aff4c2",
+ "name" : "view-profile",
+ "description" : "${role_view-profile}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "0db272fc-6ba8-45fc-b64a-ec0f21ab60c7",
+ "attributes" : { }
+ }, {
+ "id" : "4bef4c6e-b8b4-48b5-9da9-6997e5b1c736",
+ "name" : "manage-account",
+ "description" : "${role_manage-account}",
"composite" : true,
"composites" : {
"client" : {
- "account" : [ "view-consent" ]
+ "account" : [ "manage-account-links" ]
}
},
"clientRole" : true,
- "containerId" : "3dca789b-ddb0-4882-9dc3-9162dbce1a34",
+ "containerId" : "0db272fc-6ba8-45fc-b64a-ec0f21ab60c7",
"attributes" : { }
}, {
- "id" : "8a61a541-f46c-406a-8d50-0dcd3821ad19",
- "name" : "manage-account",
- "description" : "${role_manage-account}",
+ "id" : "4ee3ca7d-80d3-48a9-8abc-a81810f8a54d",
+ "name" : "manage-consent",
+ "description" : "${role_manage-consent}",
"composite" : true,
"composites" : {
"client" : {
- "account" : [ "manage-account-links" ]
+ "account" : [ "view-consent" ]
}
},
"clientRole" : true,
- "containerId" : "3dca789b-ddb0-4882-9dc3-9162dbce1a34",
+ "containerId" : "0db272fc-6ba8-45fc-b64a-ec0f21ab60c7",
"attributes" : { }
}, {
- "id" : "91b1cb2f-7fba-40e5-9988-b43d4ebb25d9",
- "name" : "manage-account-links",
- "description" : "${role_manage-account-links}",
+ "id" : "b9b776b4-6b04-469f-ab21-5afb25b1c77d",
+ "name" : "delete-account",
+ "description" : "${role_delete-account}",
"composite" : false,
"clientRole" : true,
- "containerId" : "3dca789b-ddb0-4882-9dc3-9162dbce1a34",
+ "containerId" : "0db272fc-6ba8-45fc-b64a-ec0f21ab60c7",
"attributes" : { }
}, {
- "id" : "18cdd8ee-f35c-40e6-a09a-5743388b6f18",
+ "id" : "c827cdf1-85c9-4e89-a71e-dff5bd5efb3d",
"name" : "view-applications",
"description" : "${role_view-applications}",
"composite" : false,
"clientRole" : true,
- "containerId" : "3dca789b-ddb0-4882-9dc3-9162dbce1a34",
+ "containerId" : "0db272fc-6ba8-45fc-b64a-ec0f21ab60c7",
"attributes" : { }
}, {
- "id" : "346078cb-e7e0-45f8-b738-1bf58b02251d",
- "name" : "view-profile",
- "description" : "${role_view-profile}",
+ "id" : "8517234d-dc7e-4902-b51b-d1e4084388dd",
+ "name" : "view-groups",
+ "description" : "${role_view-groups}",
"composite" : false,
"clientRole" : true,
- "containerId" : "3dca789b-ddb0-4882-9dc3-9162dbce1a34",
+ "containerId" : "0db272fc-6ba8-45fc-b64a-ec0f21ab60c7",
"attributes" : { }
}, {
- "id" : "518fb059-94bd-4b76-96b4-8c08381ceab8",
- "name" : "delete-account",
- "description" : "${role_delete-account}",
+ "id" : "558181c3-87d7-4e45-a4bf-f794c2fec2bb",
+ "name" : "manage-account-links",
+ "description" : "${role_manage-account-links}",
"composite" : false,
"clientRole" : true,
- "containerId" : "3dca789b-ddb0-4882-9dc3-9162dbce1a34",
+ "containerId" : "0db272fc-6ba8-45fc-b64a-ec0f21ab60c7",
"attributes" : { }
}, {
- "id" : "7d8f33e0-f53a-4d5a-9e0d-422a245cb236",
+ "id" : "fd7dd764-fc90-41da-8d03-dac55062f432",
"name" : "view-consent",
"description" : "${role_view-consent}",
"composite" : false,
"clientRole" : true,
- "containerId" : "3dca789b-ddb0-4882-9dc3-9162dbce1a34",
- "attributes" : { }
- }, {
- "id" : "717fdfe3-4d46-4d23-8248-5b06b73a5d26",
- "name" : "view-groups",
- "description" : "${role_view-groups}",
- "composite" : false,
- "clientRole" : true,
- "containerId" : "3dca789b-ddb0-4882-9dc3-9162dbce1a34",
+ "containerId" : "0db272fc-6ba8-45fc-b64a-ec0f21ab60c7",
"attributes" : { }
} ]
}
},
"groups" : [ ],
"defaultRole" : {
- "id" : "1d93addd-604f-4388-bff2-48849ce0317c",
+ "id" : "0de3d9a9-ce18-4638-806f-a96e61e93e62",
"name" : "default-roles-master",
"description" : "${role_default-roles}",
"composite" : true,
"clientRole" : false,
- "containerId" : "758ff4fc-bf09-403b-adbe-c9a56cadd5d3"
+ "containerId" : "6219f172-5cbc-40f1-99fc-74218bbb2642"
},
"requiredCredentials" : [ "password" ],
"otpPolicyType" : "totp",
@@ -397,7 +397,7 @@
} ]
},
"clients" : [ {
- "id" : "3dca789b-ddb0-4882-9dc3-9162dbce1a34",
+ "id" : "0db272fc-6ba8-45fc-b64a-ec0f21ab60c7",
"clientId" : "account",
"name" : "${client_account}",
"rootUrl" : "${authBaseUrl}",
@@ -424,10 +424,10 @@
"authenticationFlowBindingOverrides" : { },
"fullScopeAllowed" : false,
"nodeReRegistrationTimeout" : 0,
- "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ],
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
"optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
}, {
- "id" : "fcc26741-1267-44df-880c-0db1273037db",
+ "id" : "4b5a85e3-b814-4490-a08f-450411a65f38",
"clientId" : "account-console",
"name" : "${client_account-console}",
"rootUrl" : "${authBaseUrl}",
@@ -456,17 +456,17 @@
"fullScopeAllowed" : false,
"nodeReRegistrationTimeout" : 0,
"protocolMappers" : [ {
- "id" : "5f785b3b-9c2f-40d6-a090-2391dec074c5",
+ "id" : "cff0218a-6481-4a33-9a1d-35ffe3b9b532",
"name" : "audience resolve",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-audience-resolve-mapper",
"consentRequired" : false,
"config" : { }
} ],
- "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ],
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
"optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
}, {
- "id" : "eca9e50a-1405-4a18-ba60-50079856d282",
+ "id" : "ba46734c-078a-45a4-9ab6-6462abee8aca",
"clientId" : "admin-cli",
"name" : "${client_admin-cli}",
"surrogateAuthRequired" : false,
@@ -489,10 +489,10 @@
"authenticationFlowBindingOverrides" : { },
"fullScopeAllowed" : false,
"nodeReRegistrationTimeout" : 0,
- "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ],
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
"optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
}, {
- "id" : "6b259285-42b1-430f-b619-b83ca1b86e14",
+ "id" : "7000b14a-6262-498a-a2f5-244e4678377b",
"clientId" : "broker",
"name" : "${client_broker}",
"surrogateAuthRequired" : false,
@@ -515,10 +515,10 @@
"authenticationFlowBindingOverrides" : { },
"fullScopeAllowed" : false,
"nodeReRegistrationTimeout" : 0,
- "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ],
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
"optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
}, {
- "id" : "01702696-84f2-4815-9385-493495f5542e",
+ "id" : "4d54a69f-edc0-40da-a0e1-5a8f136913e6",
"clientId" : "master-realm",
"name" : "master Realm",
"surrogateAuthRequired" : false,
@@ -540,10 +540,10 @@
"authenticationFlowBindingOverrides" : { },
"fullScopeAllowed" : false,
"nodeReRegistrationTimeout" : 0,
- "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ],
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
"optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
}, {
- "id" : "6a9e0ce9-0ceb-4bf4-9c12-245996c2d202",
+ "id" : "cd6fc819-1bd0-4173-974a-cee8ad45e24b",
"clientId" : "security-admin-console",
"name" : "${client_security-admin-console}",
"rootUrl" : "${authAdminUrl}",
@@ -572,7 +572,7 @@
"fullScopeAllowed" : false,
"nodeReRegistrationTimeout" : 0,
"protocolMappers" : [ {
- "id" : "686aee26-100e-40f9-bff6-f09f38a48f17",
+ "id" : "5dd33aa0-3f10-4d21-a911-9849fd1d51c8",
"name" : "locale",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
@@ -587,182 +587,214 @@
"jsonType.label" : "String"
}
} ],
- "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ],
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
"optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
} ],
"clientScopes" : [ {
- "id" : "899b0c35-7ed6-4898-a421-a7472af73c2f",
- "name" : "email",
- "description" : "OpenID Connect built-in scope: email",
+ "id" : "aae7ae1c-e7b8-44a1-8b7c-a0b1784025af",
+ "name" : "roles",
+ "description" : "OpenID Connect scope for add user roles to the access token",
"protocol" : "openid-connect",
"attributes" : {
- "include.in.token.scope" : "true",
- "consent.screen.text" : "${emailScopeConsentText}",
+ "include.in.token.scope" : "false",
+ "consent.screen.text" : "${rolesScopeConsentText}",
"display.on.consent.screen" : "true"
},
"protocolMappers" : [ {
- "id" : "a2122fd7-8d95-4221-8928-0681c1403d30",
- "name" : "email",
+ "id" : "a4387c51-3ae8-4afc-856b-fc7779bd4684",
+ "name" : "audience resolve",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "protocolMapper" : "oidc-audience-resolve-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
- "userinfo.token.claim" : "true",
- "user.attribute" : "email",
- "id.token.claim" : "true",
+ "access.token.claim" : "true"
+ }
+ }, {
+ "id" : "ebe74b14-fcf7-401d-94dd-493344976566",
+ "name" : "realm roles",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "user.attribute" : "foo",
+ "introspection.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "email",
- "jsonType.label" : "String"
+ "claim.name" : "realm_access.roles",
+ "jsonType.label" : "String",
+ "multivalued" : "true"
}
}, {
- "id" : "f8a0e045-fb36-4a13-8c2e-34831232676a",
- "name" : "email verified",
+ "id" : "23becefb-f723-45f8-a10b-8bd038464259",
+ "name" : "client roles",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-usermodel-property-mapper",
+ "protocolMapper" : "oidc-usermodel-client-role-mapper",
"consentRequired" : false,
"config" : {
+ "user.attribute" : "foo",
"introspection.token.claim" : "true",
- "userinfo.token.claim" : "true",
- "user.attribute" : "emailVerified",
- "id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "email_verified",
- "jsonType.label" : "boolean"
+ "claim.name" : "resource_access.${client_id}.roles",
+ "jsonType.label" : "String",
+ "multivalued" : "true"
}
} ]
}, {
- "id" : "26251e40-1e68-4e9f-a09d-8e974d8a0f83",
- "name" : "profile",
- "description" : "OpenID Connect built-in scope: profile",
+ "id" : "1374660d-88db-4973-b069-4bca7ff7fcaa",
+ "name" : "address",
+ "description" : "OpenID Connect built-in scope: address",
"protocol" : "openid-connect",
"attributes" : {
"include.in.token.scope" : "true",
- "consent.screen.text" : "${profileScopeConsentText}",
+ "consent.screen.text" : "${addressScopeConsentText}",
"display.on.consent.screen" : "true"
},
"protocolMappers" : [ {
- "id" : "3546bbbe-28dc-4d24-98fe-25b6d976bba7",
- "name" : "birthdate",
+ "id" : "dc13ff65-fdb1-433c-864a-e9e417a020ef",
+ "name" : "address",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "protocolMapper" : "oidc-address-mapper",
"consentRequired" : false,
"config" : {
+ "user.attribute.formatted" : "formatted",
+ "user.attribute.country" : "country",
"introspection.token.claim" : "true",
+ "user.attribute.postal_code" : "postal_code",
"userinfo.token.claim" : "true",
- "user.attribute" : "birthdate",
+ "user.attribute.street" : "street",
"id.token.claim" : "true",
+ "user.attribute.region" : "region",
"access.token.claim" : "true",
- "claim.name" : "birthdate",
- "jsonType.label" : "String"
+ "user.attribute.locality" : "locality"
}
- }, {
- "id" : "cea32932-d177-4a97-bf90-2470c7cea25c",
- "name" : "updated at",
+ } ]
+ }, {
+ "id" : "2f39e5ff-3645-42de-bfbd-61c5e9e97444",
+ "name" : "microprofile-jwt",
+ "description" : "Microprofile - JWT built-in scope",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "display.on.consent.screen" : "false"
+ },
+ "protocolMappers" : [ {
+ "id" : "5613edc2-0440-4b67-a2cf-4fa42de6edd6",
+ "name" : "groups",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "protocolMapper" : "oidc-usermodel-realm-role-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
- "userinfo.token.claim" : "true",
- "user.attribute" : "updatedAt",
+ "multivalued" : "true",
+ "user.attribute" : "foo",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "updated_at",
- "jsonType.label" : "long"
+ "claim.name" : "groups",
+ "jsonType.label" : "String"
}
}, {
- "id" : "715e18d7-6065-4d3e-84e9-e0e132abac95",
- "name" : "website",
+ "id" : "aed0d46f-b959-44d9-b816-277adb346924",
+ "name" : "upn",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
"userinfo.token.claim" : "true",
- "user.attribute" : "website",
+ "user.attribute" : "username",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "website",
+ "claim.name" : "upn",
"jsonType.label" : "String"
}
- }, {
- "id" : "e75bbc3d-af42-401c-874f-52a4f93cc87e",
- "name" : "locale",
- "protocol" : "openid-connect",
- "protocolMapper" : "oidc-usermodel-attribute-mapper",
- "consentRequired" : false,
- "config" : {
- "introspection.token.claim" : "true",
+ } ]
+ }, {
+ "id" : "c5f49220-a07e-44aa-a0a3-938a935fa84a",
+ "name" : "profile",
+ "description" : "OpenID Connect built-in scope: profile",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${profileScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "79aba687-365d-4a32-9993-085e17be0357",
+ "name" : "given name",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
"userinfo.token.claim" : "true",
- "user.attribute" : "locale",
+ "user.attribute" : "firstName",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "locale",
+ "claim.name" : "given_name",
"jsonType.label" : "String"
}
}, {
- "id" : "85a3678d-781f-4720-abc7-b7644d00c190",
- "name" : "given name",
+ "id" : "e357d5ad-aaac-4763-b30a-0483e21fe170",
+ "name" : "username",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
"userinfo.token.claim" : "true",
- "user.attribute" : "firstName",
+ "user.attribute" : "username",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "given_name",
+ "claim.name" : "preferred_username",
"jsonType.label" : "String"
}
}, {
- "id" : "2cf08e4b-96c9-4d1c-8dda-972fcb31ddc1",
- "name" : "family name",
+ "id" : "4978de55-9d4c-44ef-b090-60cfe0107094",
+ "name" : "updated at",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
"userinfo.token.claim" : "true",
- "user.attribute" : "lastName",
+ "user.attribute" : "updatedAt",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "family_name",
- "jsonType.label" : "String"
+ "claim.name" : "updated_at",
+ "jsonType.label" : "long"
}
}, {
- "id" : "3ffa4a0a-b80f-49ca-af51-1914071f38cb",
- "name" : "username",
+ "id" : "a068f777-29aa-498d-8bd5-114e3324463a",
+ "name" : "website",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
"userinfo.token.claim" : "true",
- "user.attribute" : "username",
+ "user.attribute" : "website",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "preferred_username",
+ "claim.name" : "website",
"jsonType.label" : "String"
}
}, {
- "id" : "313e8b54-2446-4279-a2b0-1d0436ecd83b",
- "name" : "middle name",
+ "id" : "70882b82-8ac2-4014-926b-900e2b5dea9a",
+ "name" : "profile",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
"userinfo.token.claim" : "true",
- "user.attribute" : "middleName",
+ "user.attribute" : "profile",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "middle_name",
+ "claim.name" : "profile",
"jsonType.label" : "String"
}
}, {
- "id" : "92e5dbd5-f2ab-42d7-a297-4c1fcf3b4fb5",
+ "id" : "c3817b85-b874-4fef-8aa3-551df9fd82bf",
"name" : "full name",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-full-name-mapper",
@@ -774,22 +806,22 @@
"userinfo.token.claim" : "true"
}
}, {
- "id" : "888ae77e-149f-4e61-9b57-b977df391261",
- "name" : "picture",
+ "id" : "91b49f55-c0da-4bc4-a011-07239c9af877",
+ "name" : "middle name",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
"userinfo.token.claim" : "true",
- "user.attribute" : "picture",
+ "user.attribute" : "middleName",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "picture",
+ "claim.name" : "middle_name",
"jsonType.label" : "String"
}
}, {
- "id" : "8d9a48f6-9891-4096-b154-5ff53e4a92fb",
+ "id" : "a0c47ed4-638a-4249-af90-2ac1d041ba8f",
"name" : "gender",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
@@ -804,96 +836,98 @@
"jsonType.label" : "String"
}
}, {
- "id" : "8d465f23-2d9d-4eba-89ef-beea34735658",
- "name" : "nickname",
+ "id" : "5e321f9d-2580-44b4-9b6e-8c06518235a6",
+ "name" : "zoneinfo",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
"userinfo.token.claim" : "true",
- "user.attribute" : "nickname",
+ "user.attribute" : "zoneinfo",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "nickname",
+ "claim.name" : "zoneinfo",
"jsonType.label" : "String"
}
}, {
- "id" : "846fc3d1-6e0d-47fc-ab57-bba15b77c8be",
- "name" : "profile",
+ "id" : "ce6c6755-9351-4a3f-ac73-efc071ef225a",
+ "name" : "locale",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
"userinfo.token.claim" : "true",
- "user.attribute" : "profile",
+ "user.attribute" : "locale",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "profile",
+ "claim.name" : "locale",
"jsonType.label" : "String"
}
}, {
- "id" : "9665ff98-2323-4d76-8c68-af8fbc0b049a",
- "name" : "zoneinfo",
+ "id" : "302b2116-26fe-4b51-bf38-b43942e08afe",
+ "name" : "birthdate",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
"userinfo.token.claim" : "true",
- "user.attribute" : "zoneinfo",
+ "user.attribute" : "birthdate",
"id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "zoneinfo",
+ "claim.name" : "birthdate",
"jsonType.label" : "String"
}
- } ]
- }, {
- "id" : "5da42d73-cd9c-4867-9aa2-92074e8f8ab4",
- "name" : "basic",
- "description" : "OpenID Connect scope for add all basic claims to the token",
- "protocol" : "openid-connect",
- "attributes" : {
- "include.in.token.scope" : "false",
- "display.on.consent.screen" : "false"
- },
- "protocolMappers" : [ {
- "id" : "65e5ca75-9ad9-4ed9-b69b-aa71967d8a63",
- "name" : "sub",
+ }, {
+ "id" : "92438586-bc3e-48e9-a4c5-ca16b7970be0",
+ "name" : "family name",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-sub-mapper",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
"introspection.token.claim" : "true",
- "access.token.claim" : "true"
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "lastName",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "family_name",
+ "jsonType.label" : "String"
}
}, {
- "id" : "acc79e05-b344-43b3-918b-2832585bde15",
- "name" : "auth_time",
+ "id" : "8c61c413-c9f2-4c11-8764-930d9941b5ae",
+ "name" : "nickname",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
- "user.session.note" : "AUTH_TIME",
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "nickname",
"id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "nickname",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "491ee6ac-8ef2-48bc-b246-e55c37f59add",
+ "name" : "picture",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
"introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "picture",
+ "id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "auth_time",
- "jsonType.label" : "long"
+ "claim.name" : "picture",
+ "jsonType.label" : "String"
}
} ]
}, {
- "id" : "320b51af-0c74-4d71-b6f4-dc262b4297f9",
- "name" : "offline_access",
- "description" : "OpenID Connect built-in scope: offline_access",
- "protocol" : "openid-connect",
- "attributes" : {
- "consent.screen.text" : "${offlineAccessScopeConsentText}",
- "display.on.consent.screen" : "true"
- }
- }, {
- "id" : "84bb2402-4693-4078-9cf0-8d8fa2d09408",
+ "id" : "85a4c487-8c44-4f76-b410-4a27c4083f47",
"name" : "phone",
"description" : "OpenID Connect built-in scope: phone",
"protocol" : "openid-connect",
@@ -903,7 +937,7 @@
"display.on.consent.screen" : "true"
},
"protocolMappers" : [ {
- "id" : "b5f014fb-0ab0-48cf-a676-8e1c5dadef0b",
+ "id" : "d6b080b8-3d56-4e43-acb1-3c1b070fe8af",
"name" : "phone number",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
@@ -918,7 +952,7 @@
"jsonType.label" : "String"
}
}, {
- "id" : "bf410999-86a7-49a6-9c3c-05fc8cb83605",
+ "id" : "cfecf6e0-9e79-4436-9d39-ed55e900a67e",
"name" : "phone number verified",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-usermodel-attribute-mapper",
@@ -934,167 +968,112 @@
}
} ]
}, {
- "id" : "ab92a399-0b8b-4821-96a9-feafef914549",
- "name" : "acr",
- "description" : "OpenID Connect scope for add acr (authentication context class reference) to the token",
+ "id" : "bd1afe0e-1af8-4cba-bc93-c77b558d9067",
+ "name" : "basic",
+ "description" : "OpenID Connect scope for add all basic claims to the token",
"protocol" : "openid-connect",
"attributes" : {
"include.in.token.scope" : "false",
"display.on.consent.screen" : "false"
},
"protocolMappers" : [ {
- "id" : "2b06dd12-3493-4f63-8878-0d847514e641",
- "name" : "acr loa level",
+ "id" : "42df3f15-5f54-4b88-9541-bcde05766379",
+ "name" : "auth_time",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-acr-mapper",
+ "protocolMapper" : "oidc-usersessionmodel-note-mapper",
"consentRequired" : false,
"config" : {
+ "user.session.note" : "AUTH_TIME",
"id.token.claim" : "true",
"introspection.token.claim" : "true",
- "access.token.claim" : "true"
+ "access.token.claim" : "true",
+ "claim.name" : "auth_time",
+ "jsonType.label" : "long"
}
- } ]
- }, {
- "id" : "46dd6349-36e6-476b-9dbf-180bc8a31b83",
- "name" : "address",
- "description" : "OpenID Connect built-in scope: address",
- "protocol" : "openid-connect",
- "attributes" : {
- "include.in.token.scope" : "true",
- "consent.screen.text" : "${addressScopeConsentText}",
- "display.on.consent.screen" : "true"
- },
- "protocolMappers" : [ {
- "id" : "711afd99-66ea-43df-8275-199b0900ca1a",
- "name" : "address",
+ }, {
+ "id" : "9186563e-5761-4c48-bd15-1f59e51c882a",
+ "name" : "sub",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-address-mapper",
+ "protocolMapper" : "oidc-sub-mapper",
"consentRequired" : false,
"config" : {
- "user.attribute.formatted" : "formatted",
- "user.attribute.country" : "country",
"introspection.token.claim" : "true",
- "user.attribute.postal_code" : "postal_code",
- "userinfo.token.claim" : "true",
- "user.attribute.street" : "street",
- "id.token.claim" : "true",
- "user.attribute.region" : "region",
- "access.token.claim" : "true",
- "user.attribute.locality" : "locality"
+ "access.token.claim" : "true"
}
} ]
}, {
- "id" : "e87b9d27-b432-4459-ab13-e7c035625bed",
- "name" : "microprofile-jwt",
- "description" : "Microprofile - JWT built-in scope",
+ "id" : "10faa820-bd35-47f6-97b3-dd2820c4e9e9",
+ "name" : "acr",
+ "description" : "OpenID Connect scope for add acr (authentication context class reference) to the token",
"protocol" : "openid-connect",
"attributes" : {
- "include.in.token.scope" : "true",
+ "include.in.token.scope" : "false",
"display.on.consent.screen" : "false"
},
"protocolMappers" : [ {
- "id" : "a68090d0-c1f7-48e1-9f32-5d2ec77457d8",
- "name" : "groups",
+ "id" : "bfef859b-30ac-49ad-88dd-fe43425c0290",
+ "name" : "acr loa level",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+ "protocolMapper" : "oidc-acr-mapper",
"consentRequired" : false,
"config" : {
- "introspection.token.claim" : "true",
- "multivalued" : "true",
- "user.attribute" : "foo",
"id.token.claim" : "true",
- "access.token.claim" : "true",
- "claim.name" : "groups",
- "jsonType.label" : "String"
- }
- }, {
- "id" : "2b4f0429-6464-4ff7-b514-742fd9406bd0",
- "name" : "upn",
- "protocol" : "openid-connect",
- "protocolMapper" : "oidc-usermodel-attribute-mapper",
- "consentRequired" : false,
- "config" : {
"introspection.token.claim" : "true",
- "userinfo.token.claim" : "true",
- "user.attribute" : "username",
- "id.token.claim" : "true",
- "access.token.claim" : "true",
- "claim.name" : "upn",
- "jsonType.label" : "String"
+ "access.token.claim" : "true"
}
} ]
}, {
- "id" : "a4d66eac-66c9-40e7-9c0e-2de645c4a415",
- "name" : "role_list",
- "description" : "SAML role list",
- "protocol" : "saml",
+ "id" : "003d13b6-5b72-4f7b-add9-dab6330ec555",
+ "name" : "offline_access",
+ "description" : "OpenID Connect built-in scope: offline_access",
+ "protocol" : "openid-connect",
"attributes" : {
- "consent.screen.text" : "${samlRoleListScopeConsentText}",
+ "consent.screen.text" : "${offlineAccessScopeConsentText}",
"display.on.consent.screen" : "true"
- },
- "protocolMappers" : [ {
- "id" : "6148e600-1a63-4caa-946a-efe35d0a3bb4",
- "name" : "role list",
- "protocol" : "saml",
- "protocolMapper" : "saml-role-list-mapper",
- "consentRequired" : false,
- "config" : {
- "single" : "false",
- "attribute.nameformat" : "Basic",
- "attribute.name" : "Role"
- }
- } ]
+ }
}, {
- "id" : "8f865f22-1e06-4426-a2af-1e3b683c6450",
- "name" : "roles",
- "description" : "OpenID Connect scope for add user roles to the access token",
+ "id" : "9f4285c8-31e0-4339-ae6c-7eb9725da69b",
+ "name" : "email",
+ "description" : "OpenID Connect built-in scope: email",
"protocol" : "openid-connect",
"attributes" : {
- "include.in.token.scope" : "false",
- "consent.screen.text" : "${rolesScopeConsentText}",
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${emailScopeConsentText}",
"display.on.consent.screen" : "true"
},
"protocolMappers" : [ {
- "id" : "b1dc3cca-f0bd-45c2-a52d-f9aef46deebe",
- "name" : "realm roles",
+ "id" : "651f856b-739f-4797-b32c-49a9f571223e",
+ "name" : "email",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
"consentRequired" : false,
"config" : {
- "user.attribute" : "foo",
"introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "email",
+ "id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "realm_access.roles",
- "jsonType.label" : "String",
- "multivalued" : "true"
+ "claim.name" : "email",
+ "jsonType.label" : "String"
}
}, {
- "id" : "8c5de524-3ba5-4f03-9f8f-a0f45e48df6b",
- "name" : "client roles",
+ "id" : "d8e18659-6fdc-4c40-a65e-4d855f514cf9",
+ "name" : "email verified",
"protocol" : "openid-connect",
- "protocolMapper" : "oidc-usermodel-client-role-mapper",
+ "protocolMapper" : "oidc-usermodel-property-mapper",
"consentRequired" : false,
"config" : {
- "user.attribute" : "foo",
"introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "emailVerified",
+ "id.token.claim" : "true",
"access.token.claim" : "true",
- "claim.name" : "resource_access.${client_id}.roles",
- "jsonType.label" : "String",
- "multivalued" : "true"
- }
- }, {
- "id" : "e8786aa2-884c-40e0-b276-eb7fbd855791",
- "name" : "audience resolve",
- "protocol" : "openid-connect",
- "protocolMapper" : "oidc-audience-resolve-mapper",
- "consentRequired" : false,
- "config" : {
- "introspection.token.claim" : "true",
- "access.token.claim" : "true"
+ "claim.name" : "email_verified",
+ "jsonType.label" : "boolean"
}
} ]
}, {
- "id" : "f1a9e164-cb83-4b91-ac53-7dfe3f6729a6",
+ "id" : "5139ea54-1669-4a7d-980e-e8a9d7a83d57",
"name" : "web-origins",
"description" : "OpenID Connect scope for add allowed web origins to the access token",
"protocol" : "openid-connect",
@@ -1104,7 +1083,7 @@
"display.on.consent.screen" : "false"
},
"protocolMappers" : [ {
- "id" : "18d62bcd-170e-47c7-93ae-4072f19a1853",
+ "id" : "febb8ed8-fc30-4d3b-8cc0-729718b3ea7a",
"name" : "allowed web origins",
"protocol" : "openid-connect",
"protocolMapper" : "oidc-allowed-origins-mapper",
@@ -1114,6 +1093,27 @@
"access.token.claim" : "true"
}
} ]
+ }, {
+ "id" : "4f6e34b8-158a-4e79-9673-4bc54d984ee0",
+ "name" : "role_list",
+ "description" : "SAML role list",
+ "protocol" : "saml",
+ "attributes" : {
+ "consent.screen.text" : "${samlRoleListScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "cb55abfc-fda7-4c0e-9b04-fe3059b2b021",
+ "name" : "role list",
+ "protocol" : "saml",
+ "protocolMapper" : "saml-role-list-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "single" : "false",
+ "attribute.nameformat" : "Basic",
+ "attribute.name" : "Role"
+ }
+ } ]
} ],
"defaultDefaultClientScopes" : [ "role_list", "profile", "email", "roles", "web-origins", "acr", "basic" ],
"defaultOptionalClientScopes" : [ "offline_access", "address", "phone", "microprofile-jwt" ],
@@ -1137,57 +1137,60 @@
"identityProviderMappers" : [ ],
"components" : {
"org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ {
- "id" : "e76aa8ea-4198-41dd-b498-9951d1459df4",
- "name" : "Allowed Protocol Mapper Types",
- "providerId" : "allowed-protocol-mappers",
- "subType" : "authenticated",
+ "id" : "00642647-1062-4330-8624-4be0a926d7be",
+ "name" : "Trusted Hosts",
+ "providerId" : "trusted-hosts",
+ "subType" : "anonymous",
"subComponents" : { },
"config" : {
- "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper" ]
+ "host-sending-registration-request-must-match" : [ "true" ],
+ "client-uris-must-match" : [ "true" ]
}
}, {
- "id" : "fa3f9cf0-c53a-48bb-adb8-f27f66e3568e",
- "name" : "Full Scope Disabled",
- "providerId" : "scope",
- "subType" : "anonymous",
+ "id" : "7ab2c08b-901f-4b95-b303-1fa87fab5034",
+ "name" : "Allowed Client Scopes",
+ "providerId" : "allowed-client-templates",
+ "subType" : "authenticated",
"subComponents" : { },
- "config" : { }
+ "config" : {
+ "allow-default-scopes" : [ "true" ]
+ }
}, {
- "id" : "10077ff3-12ce-40d5-9108-2de23a14d541",
- "name" : "Consent Required",
- "providerId" : "consent-required",
+ "id" : "a1ac08b2-1946-4610-854e-7b301164b98b",
+ "name" : "Max Clients Limit",
+ "providerId" : "max-clients",
"subType" : "anonymous",
"subComponents" : { },
- "config" : { }
+ "config" : {
+ "max-clients" : [ "200" ]
+ }
}, {
- "id" : "fb43aaf7-481b-462c-9cd3-062d44a42492",
+ "id" : "75084497-05b2-4978-8088-fe920f5e165e",
"name" : "Allowed Protocol Mapper Types",
"providerId" : "allowed-protocol-mappers",
- "subType" : "anonymous",
+ "subType" : "authenticated",
"subComponents" : { },
"config" : {
- "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper" ]
+ "allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper" ]
}
}, {
- "id" : "b92ef2e1-c333-4daf-80b2-b0dc016bb613",
- "name" : "Allowed Client Scopes",
- "providerId" : "allowed-client-templates",
- "subType" : "authenticated",
+ "id" : "cd373617-6545-43f2-954a-035b08da1d4b",
+ "name" : "Allowed Protocol Mapper Types",
+ "providerId" : "allowed-protocol-mappers",
+ "subType" : "anonymous",
"subComponents" : { },
"config" : {
- "allow-default-scopes" : [ "true" ]
+ "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper" ]
}
}, {
- "id" : "dae5ff77-754e-4b08-ae16-18e2105a20a8",
- "name" : "Max Clients Limit",
- "providerId" : "max-clients",
+ "id" : "843e6e4b-caa8-42ed-bbb2-be158983514e",
+ "name" : "Consent Required",
+ "providerId" : "consent-required",
"subType" : "anonymous",
"subComponents" : { },
- "config" : {
- "max-clients" : [ "200" ]
- }
+ "config" : { }
}, {
- "id" : "7cfe8082-e7b6-4fe2-805f-4bab1c80f66b",
+ "id" : "bb925f89-8bd3-44cd-942a-d2615fda21f6",
"name" : "Allowed Client Scopes",
"providerId" : "allowed-client-templates",
"subType" : "anonymous",
@@ -1196,18 +1199,15 @@
"allow-default-scopes" : [ "true" ]
}
}, {
- "id" : "a0aa3cab-ce51-4f90-af7d-22a8a4d425e0",
- "name" : "Trusted Hosts",
- "providerId" : "trusted-hosts",
+ "id" : "d8d6abb4-2ea7-4a13-b325-f7bf359b929a",
+ "name" : "Full Scope Disabled",
+ "providerId" : "scope",
"subType" : "anonymous",
"subComponents" : { },
- "config" : {
- "host-sending-registration-request-must-match" : [ "true" ],
- "client-uris-must-match" : [ "true" ]
- }
+ "config" : { }
} ],
"org.keycloak.userprofile.UserProfileProvider" : [ {
- "id" : "9adea1fb-e00d-4b4d-80dc-49ad060e17b8",
+ "id" : "1ecab23b-5b5b-4252-ae04-f02d82a10fbc",
"providerId" : "declarative-user-profile",
"subComponents" : { },
"config" : {
@@ -1215,55 +1215,55 @@
}
} ],
"org.keycloak.keys.KeyProvider" : [ {
- "id" : "491a8374-2165-4639-a5e0-ed46056fc8ef",
- "name" : "hmac-generated-hs512",
- "providerId" : "hmac-generated",
+ "id" : "1c046623-2414-470d-885d-676b218f903a",
+ "name" : "rsa-enc-generated",
+ "providerId" : "rsa-enc-generated",
"subComponents" : { },
"config" : {
- "kid" : [ "837b86f8-185f-44d7-a971-08fd21361790" ],
- "secret" : [ "0h-TQyfcIzi_NhnjYmj01XQE9cT91JiiXTyQiP2vUNCaEVxYzuEiPrWdKyQrCerNrQWl_BfQvF752F0Ri_CeaCb4oOgdbXtpYHIe39Htm2sR6XboBAo2krQiigZpXpiBFq9vnZoCqk7QYbdPQfCB3b1sPqiQksjKPlU98MBVyTs" ],
+ "privateKey" : [ "MIIEogIBAAKCAQEAtjMAtyi53OP5PDhUMn0XxLfqUt2Z8nYezDWdxVOSGLRb/zYLK3WaXCwrz88OyBeDHq4QnwD3kGtBmVfJl1jPwEP0QBAVeI3adQJnJhqUpKp7a+ERFQiIlgxhtTWauZxZfwJ1LqDRZ65Th+n5Wldd27J08ex47AHjerCTi8VESCI1+zrZpteNHbHhM30KfXMobnM3wjRtxu8TGtMNZvLA+X1y2bdL4tCcjqBp1JoAOJZRPm2XW6HDmGW3z/LZYI3qffr/xo/JWtjFCrjSfIuuy41bvxkGxkt0AJu6wrlckoAos9PhzJrXIZoqxqdJ5KECid4PlBXxNu3ayT5qCCuuHwIDAQABAoIBAAjqcAOGe6niggS/YOdjlbErqszJSUpDG3i0uva4AzMwSDwx4dQLmjUeeDpgEIIcHG945xlQy8yGYxxk3lmIoAnxiVdFMjfHAUSujGuh61oveYCq79IOq9hj3LgoWlzw2LRNY3yXpAel0TKacXhJRC+HCQ/5mWU7Jm2PjHjPe2roJIOaojg5Z9oUKX4do69aZsRYjukr4MOn79MJ8Y2t+CCFkpRunh753c9I7FjTBMr0ejjLPcdSRl2qQcVeS9XExCdxB9u1sSn7WftfwyKVoks65DIVhANfvNjzDa3gDWvEETjNm/HPmpKcb1fLilvxjGZkknnzj0e67cJxfYGhyrECgYEA386QURCw4oXdTUs1ZbF3HEvc+5URl29IDIKBAPkS+euIXqhTXM0DXrvjNM+7ISZyO8giYTvHxOl1/uKgAEtpapdlkMdLTgQW5p46rQXpufQrn9mwyJlKI39kgyTnmqZMNjBDoe+/Uq9DVjhldRmXJ+snD/T+hsIbuMWMwt2ONLkCgYEA0GhIroPSNH4gIHUpPwUh9HJ3Ungb5ckwIJ65nVekFWdiwDdci7woqJ4TXjqkyf/CcXqlsA18yKV3oVQiI2UUYYzs0YW6tphplbmLb8DPEUUge48PJmWKmLEea9P2X6wQbQ5kr1hiJvQ252BJe24MntXgW8cpMst+mK9g36xOvZcCgYA3vvfreUDV64oH6qfOQLnubmcIs0TCd5F2rDr9xwyW+7fn+/1nrBkey6X4TZXK2Ay0H1GQ7pb/0Tb22fQInsAPMM63lSyIrjQWFWuAFWz2SH9lPY/vJ190IBMlJ1gZCTsKdFMkTtdU/RrEqx96X3lrFAOS0e9kGY1WJL6++vik4QKBgEjPJhVSGG4eYjr0s6RAtswf8W/uZlCxKQ88ZLyDkd+obueYb8yhv9Ko5ztUYZ3wrI3Yu2n2TFIM/O5v5j1XYvdxtIq+nayNMtYMLJquUalG7UI9iJ1xfCo8NtSVCM4D3vk6vhJEXoYda9EJ4qIsoFwdfHST7+C/F0tgegequxehAoGAesBnMgX8m5uENZ5CzeX2jmcz/o01Kr6RmVyo0DFILOhhyO8cIyQg96r1f7/D73Q8GZ5V23FB9y8hgU9dtGpoM52Ty9HA3miceaKJjTkd9c4Lq7Vt74Ho0/WY+LE7lCL3hHBQd+79LfZhSnTrZx7rYMnJjB5qVhJ4jheMumOd4rE=" ],
+ "keyUse" : [ "ENC" ],
+ "certificate" : [ "MIICmzCCAYMCBgGSDEEpTTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQwOTE5MjE0NTQ5WhcNMzQwOTE5MjE0NzI5WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2MwC3KLnc4/k8OFQyfRfEt+pS3Znydh7MNZ3FU5IYtFv/NgsrdZpcLCvPzw7IF4MerhCfAPeQa0GZV8mXWM/AQ/RAEBV4jdp1AmcmGpSkqntr4REVCIiWDGG1NZq5nFl/AnUuoNFnrlOH6flaV13bsnTx7HjsAeN6sJOLxURIIjX7Otmm140dseEzfQp9cyhuczfCNG3G7xMa0w1m8sD5fXLZt0vi0JyOoGnUmgA4llE+bZdbocOYZbfP8tlgjep9+v/Gj8la2MUKuNJ8i67LjVu/GQbGS3QAm7rCuVySgCiz0+HMmtchmirGp0nkoQKJ3g+UFfE27drJPmoIK64fAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAaSiN9JaOTMBNblfin32x8ExMZHFWpVeILIj2jjxhEOKV/d9SHkpKVfccup5aqJzn9mP9oHGNGbekLwW/X/3VWSCIQ7AtVrmmgtJgXEQ5zcW4CQRqtFdE+0IhbKD0Ui06qmU1kEpAUIhn2w9rquDPiHqHxR6K4iz2heESGhbKsYHLrX0zcfljV6ZiipC2OLK1ca+1wg1Ba3FUGy9+kAto1b6VOXS/+dLSxcpBpFzfiyDO1ijavD0y/J8gtNN0+kAilC2EcJQfIiLKg10FCDyHmG9IFV0g227rYpCGzQA5ljVLkB7mXkz0ieofbcRFqyuwRPve+JwBhonlYDTumDkMc=" ],
"priority" : [ "100" ],
- "algorithm" : [ "HS512" ]
+ "algorithm" : [ "RSA-OAEP" ]
}
}, {
- "id" : "039e4b49-09f6-4eea-abcc-5629093d48c2",
- "name" : "aes-generated",
- "providerId" : "aes-generated",
+ "id" : "96b35fdd-5cff-4ec8-aa78-a10b25a8889b",
+ "name" : "hmac-generated-hs512",
+ "providerId" : "hmac-generated",
"subComponents" : { },
"config" : {
- "kid" : [ "b38fa3ab-54fa-45ea-a3ec-53b06c6ebd1b" ],
- "secret" : [ "ECSK8BJxfH0KE7WbtROdkQ" ],
- "priority" : [ "100" ]
+ "kid" : [ "366e0455-d4e7-48a6-ad3a-50faee7b1bdb" ],
+ "secret" : [ "aHkCWF79XyKGruLZzIu5GuPq6Olu5kLhQKf0g7btkTQWrX0jGm3HfuEKiZm_-sMhonsafkU_GAerocJGHT1-GYsuDCHixJk0hcfY5H4u3PA1SJrA4g5qVCYocdVtAS-LsxpBdfmbnKBjegKnXrS74Mbo5B_zEMxzducY0A-eRu4" ],
+ "priority" : [ "100" ],
+ "algorithm" : [ "HS512" ]
}
}, {
- "id" : "edeffc5b-ad14-432b-8816-98178a0b0292",
+ "id" : "686cb55e-b9ac-48a9-bbe7-470d6fa1304a",
"name" : "rsa-generated",
"providerId" : "rsa-generated",
"subComponents" : { },
"config" : {
- "privateKey" : [ "MIIEpAIBAAKCAQEAqgJfKoXnolBDcsRHxXxwwe4eQOcnJpDZ2agQ5hbtOXRqbPeKBlcRHUf6ecjqQjdaWmUOJxIGSNbYNSW/Lw3pyRL939xZiUOugJR9iiYru7TjqPj5Ts3qALryBcJ22iDu3goCysxQeQfWF2U/PuVKZ+OBIZXQ0/Nq6WRIMLopIImh+lVuBTkQzKDgDMIZ88469JFKbWpRZ2zxX5zthhDBtGpDi18mDaZE97Je1d8nvQI/0kWzj2C1pGhZnltEhdHG+SC12hEi8MmUYk7tDUQhJpl3jxIDkQDdGXplks+Hnercj41Hlitt/jT6zjw/AqweGmmNGRYCCD+KTAsAJtG0SwIDAQABAoIBAEza86CqljOHa2ZnmzaI8gSJm/2lQcqqcwF1e+Y4eRefLDmEkk4ZcDA3iOEjVduHYH467vH0sQier3EfVlV0SbrPrhtUZtmp0ipodnRMmzqpJL4Ph8z7Q4z+9khqSAaGGtYf2nFJehus0jkTWUsaps9eRtMjAhu/EBbgcc4takg9k25hfg4Aj/VWRfdqYK9yT6zmgMhhi9TnxHACQtpyz5MfMUgbDzvg31ztqbRAU2YPPbnCjmWcFrZALCq0sBtQXPlZbthOcyiGHvUuTBMUuTeXu2Tbo9Rk7oLiLDYKDtC8cOC/3ldJxTEGVyA4vCC+D2m7g2cY2FEewsC2648GiLECgYEA0jbseH337iinUOTYxInvCErS1PD5WrOuuYRP2qCp8rz4UbVRWPN3Y5fvyTzTZ3WsFRo1vTsEvPEDioFj7JuOI+SAxewW82cvpWSdtBzc4Rouh/XQuIy3gygagHdQaD98yWpEwH+fX4nmRoe+g5YMsgVQzMM/Cr2Jo7ICCipNKXMCgYEAzwmx1OEWT+A1JuYrZmuMVy1XYJf+a3pqPod8/PFCdxcvRN8QM0wS8VOenbQgNPFmDOq/JM6JFz4xAQgrSxeZJveSK7nYUYoFtKeRSuZj8mQl2mXTLYRRnxIS8IC0G+WlqgdwtxGjX63m9jvu7on5SyDZSKEmhs5/tP2u4x2M88kCgYEAnpa0+4n9G30sDQk4x71Pya+5MtDBLb5U2LyLCeMfk3Mg23Ow9SxoK4iaa/Upf+n0cs8dL69wuaISC9HlssEAEO/4fljIT8TO2zX3C8SilmgMJqI6XqA6agY9SCG7VYpf+Avl5lvhvk/om9kYz2jKFxuPg4rg6pdnWUmX5FdZcyUCgYBtAtLCnt2Loyb5W1ngrKIRSMtoDb+lQahtUhOKb1GquOdnoPe7usOCk5/Bs5T9q1krVfLc426lcVaGD5IUENHQBazOHyV6EW1dqJlE0bgwaXDQ5KpjnfcIBZE5Vtr+kVVACHjdu4jFGSCx5+6vZLCBUUN3DXrmohX161jJNsb/mQKBgQChMC4QSxsXMYmPAx4L8QeXN0efQDKmdFc7afyYYNHIIaxKhgJ9YJCFj0demYD2ml/TldZDjvNWj5t+vbNcHWU0MokznEb/YpYRmj//yz4KwNe7qCnqHW3FNeaGf+nONH0dByPkE6jA2UuTwY2m4qDVfx7Pv+WwRF3mqeDXdfe6yA==" ],
+ "privateKey" : [ "MIIEowIBAAKCAQEA1jaSmeEVgvMUvirpsQ0gtrWJuunJ5gQXk5HZAcx2yO4yDWGsDO6qAMTVmdsjO6EkTIkL4BPqAyE/0DZ89VkEf+69OXWhdFXD7dv0ZufBOZezpTDiZ6cdgQCyaofAsHRmWekaEAgJMTZ6iTT1973rK1W96cXukC2ozk+YDG4w6PCZDpfTpq+KYol8qt0qCjfqPewgHZ+0aEHmM9DeX5RO8o/Z+i5N88R39VnsNYpVvTIlRV/GJ6d+zLDI7l50QxKPNngruD4Z+B3kYQe/e5DcJBoKL45oNfkb+uiV/OuabmyajN1RS8u0FrVUd0emS02dkLuL6TfyYsVInRLzAiQMNwIDAQABAoIBAAs35Bk98e/1MKwS4uvcSaR367odCJn3XeVjDnqAeDoRS2VrAjp9J0G6DTZXr8fYKmaoXgsCpU87pwli88wE45jwP6WqNOXloJ4CK7xV58ckht/K/cMQO+8nwlrqOBulmj9G12VpM6i0TITcqq2qRbjJGT83F/AiDASd+NMHKaA78jj+ZWHmFarTIwfB03Zdznb/8vRGFSsyjhQgOPXZZoZdUu1GJEmnY81/yyZP92n/Cf2gjhZU5obzDHDBk2jhS50M0PVpcem8VD5gIKFAhOZWCJfZUj34eUbcEgg5/6QQE3KAJ7GGSu+pQ1B9l0dJ6EfGv4vl+V4jpfO7FqWi0/ECgYEA8/RknVDMkM3lZ33Vwri+6N8pwlYJ2kRBQEYFJK5TtKu2fSXTqAFhodYKaIJh/f5kQjJniFf2p4Rtmwwde/aoxAdVBinTKRNKlSz4kM0c3vTOCkVSJrW6t3zyTAPBkzk5iPMTi0ghQJ46zUjf7UZIsB6NjI6cf072cBlxUYYaiKcCgYEA4Mo+q7po0ahfLH4hNQ5fa/JWw3OyCdTcJDGTAcB9v+yVXa4SmoZxfwxuuyYAsc0dxa+wZZNMx1Tf6QQUFIVlXlvSLid+LEpClZ/clguQzl3OyIq01XAUSAYsBoxMzwaT9VnSKaN/WrLBMKPG8738GJgbE+EzV2vlUJ9/432xQfECgYBp5vQunr7PNbKapLPBHjYyHX6hUHxidjLlVgAxlkPcMJa96UfirQbXHHXUPJWRj3eyjPMI6za2LfTu0+mQwNkukAhG7q0uLaO48pbNNV2NJDS1nLY2+7kcom8EtLS51qO1YeBgHGXjCU15hGNBO7ueSQUluVsSoRK2QzVAMLkgDQKBgQCwUHHPqKrGp9XexB+vydI2jSJYs8qVw4vYJ7oyyZTYkOynSf31jjY/fLTtveUVkNklUaR+R4cVYhEuZ7CIWAkmdcbpxLhGbQjE61rNpcyy0Ql8aq9kKkD+LTki+bDVQUeUTht15XPi5Ap76DoIvJ+betLiSOVIUKzRDAn3mYMLQQKBgDTNljhvgzvlVvtm0+bpjtJk5j9sJ1yVo1iD8hGKZoFPUzqQ0DFcvf3NXQsZLVeLuyN9WajiuTqhuEp3zfIWyajhd1mPpNl/ZO1j/Ct4rY94awT5QXsZurlrj1HmUTFkmGGJLhBZeu4YhmZBSRojJscbzFeMQmS474Wid5lZtw9I" ],
"keyUse" : [ "SIG" ],
- "certificate" : [ "MIICmzCCAYMCBgGQN2wk5DANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQwNjIwMjA1MDUyWhcNMzQwNjIwMjA1MjMyWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqAl8qheeiUENyxEfFfHDB7h5A5ycmkNnZqBDmFu05dGps94oGVxEdR/p5yOpCN1paZQ4nEgZI1tg1Jb8vDenJEv3f3FmJQ66AlH2KJiu7tOOo+PlOzeoAuvIFwnbaIO7eCgLKzFB5B9YXZT8+5Upn44EhldDT82rpZEgwuikgiaH6VW4FORDMoOAMwhnzzjr0kUptalFnbPFfnO2GEMG0akOLXyYNpkT3sl7V3ye9Aj/SRbOPYLWkaFmeW0SF0cb5ILXaESLwyZRiTu0NRCEmmXePEgORAN0ZemWSz4ed6tyPjUeWK23+NPrOPD8CrB4aaY0ZFgIIP4pMCwAm0bRLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAE4JX1hmGcOm/bCB21uOP1+Kkc6uydaZPbvxbibEk1zqtHOnPOnJwNw4m6r6POdZD5k54k0fq4KIIBF1zZwCmwLy+OFto5MzIo13gQQTiieFjMxV/b4XfhaHwYJJiwhDyrZQYjMNL9JvNfKjcBBlKdIhjDQT4M8xLo0ViJnKt03C1JdVBcSiopa3PNMjqNpzay8QosLQ9bfkv3X1mN5NXTkyY2mOHpRhJPzvUrP+ZCUws9PVNgpcoBxQ7SA5E2u67yHFN0x9C+BxbDBvhicoGq6WyT3TSgGHf6PjaAafmiYhmL3/tdX1fM9sh8qZI72296q8pGx0T+Ubs3/WcuLbuyg=" ],
+ "certificate" : [ "MIICmzCCAYMCBgGSDEEoqjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQwOTE5MjE0NTQ5WhcNMzQwOTE5MjE0NzI5WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWNpKZ4RWC8xS+KumxDSC2tYm66cnmBBeTkdkBzHbI7jINYawM7qoAxNWZ2yM7oSRMiQvgE+oDIT/QNnz1WQR/7r05daF0VcPt2/Rm58E5l7OlMOJnpx2BALJqh8CwdGZZ6RoQCAkxNnqJNPX3vesrVb3pxe6QLajOT5gMbjDo8JkOl9Omr4piiXyq3SoKN+o97CAdn7RoQeYz0N5flE7yj9n6Lk3zxHf1Wew1ilW9MiVFX8Ynp37MsMjuXnRDEo82eCu4Phn4HeRhB797kNwkGgovjmg1+Rv66JX865pubJqM3VFLy7QWtVR3R6ZLTZ2Qu4vpN/JixUidEvMCJAw3AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJl6tFjscJN3s1xZ8WMykK6x8rYDFwGB/rsRnh5NiNJSF9c0Uv0JDXjAT5ShTBOr1YBahcIjsGGmoDgayxWCWnVuDGiJ/ChUmZ+pzw78g8H2MuXyG8L/46/73X7CHc3Xd8nXA+gCU1cCTubImQfAa+XTDvI359LXkd8V+Euo5JCnaeMT//73p8VS25exoLuO74H9yCHtR1pdIJf4ChAXnDF/kUPJk0Xzzn9cUOv7kZYSD0/ZXX9zljuF11gmC/qtSpdVlrP0n3xkBFXPuCb6XxuFk1oVyqDBOKLaO86qzebnjYLaaUUO6WgLlg76zecgyL9elHEbDY8B05ss91EE1kY=" ],
"priority" : [ "100" ]
}
}, {
- "id" : "1e8aa950-265e-44a7-aeec-bf9e9b8a7250",
- "name" : "rsa-enc-generated",
- "providerId" : "rsa-enc-generated",
+ "id" : "7f09e245-5513-4c92-8162-f95bb1f160f8",
+ "name" : "aes-generated",
+ "providerId" : "aes-generated",
"subComponents" : { },
"config" : {
- "privateKey" : [ "MIIEogIBAAKCAQEAysVkfW/UrOSBpWTCpJMdTugBWemjdE1TZeVQnvACtV6o58QY63Idztnobb1XfHqpmn3y8qTcNx2jRL9iWuMMoke49lHpckVcOl3Lv+LzSu0VenwsN7FE4kUKb9QUlXOY+wTIBNtqHgiqvMKKCdMwNesWFDeau8rpM14m5r+74Dw+naYUv+/n3HlI0S5L3unKxEHmLAFA1jgPij6E84Gax9zf0GiwvXq/YAF6vksbmE5V6s7btU2yuHxjAF2YsldEnbYbFXeUS+Y6JwZ9/Yhk8Rfm7Mc8bKeBuSUl6SmLjAv7utp8ePY8ArK6fm5eMhkhZHUKcpZ4vrb1noa2y3V9VwIDAQABAoIBABdh4SSrMKsp7olUBTNVLkawb6Ieqb/6QBO6oywGIUnTkJv+pkuq7SUH8SA2eqWFaj7BJ12JBUaVya4JI8kMmvhbrPM6nuDpKVQnB3J+iUT/8eod8jtkhbz8mSeBcp4z+6rL8lodCIT4xYzezMGKnj9EIgJS0dULS7j7XSEJcHDQTO7hIAt2QEJYy1ftAsf0zZ/6KBsiNO1h4C6WcOgsVLS+YSC6VTUQi0eeqicCp/SLIFaXE58pVoUlsKAlMnH2syzUNLzrYFnblD10F3fmrg09VzVIEG9lA5CkNHMDXf5LC2cwqo4x/OrPr1Fo0fOB/CrNe1TToVHO5Xz8JJ9beIECgYEA91oYyXAXRus5ndulU8UfODkJo0f0NWKlss8dYz8t27uOgne2blB6LsczD8XgH/LQ46GnKa9+vMwqcuOjb3b61kbLROrm/Qfhba8dcuPsCUvJvChM+DUqi9wETnOBK6PadwBUWTb8VAghi0eenThc/GMhgKyQjEnyD18yurV+B7MCgYEA0dxHO7W1LtVM7zm5NHRodr2KuzbOiHwDW/4codd4KlNiCekE+6BL48lt4jJWmmLmydlvQOWSm3ZLa07BHoLGTmxYzriP9e/JbMWstzoxYmDPMNI7kDQ7dcM1/MsHAhYjGSiAHeBaugSeZByFNOe3RxQmWF/Nh3Y1Bl1DTymn4c0CgYAtB8b5bSGftJURqvoHLRzI5IFfq2rHCUV3LwN/nPHhTdzc3aRlotsLhxJBrdlml5L1zekbyqo8/sI/ljebxEJYHh1FV6pjqDqe+EFZOCsxag245nFUwoETYyOZkKeUZUkRXwr8DumS9sP8kjZLEwbCn91qin/qOlAKAl++4+mkxwKBgE9AHVJqK1LVUCljJhKuBykYKQTMDLC0DFy4GL3xbbqmJHbTnYMcpKwPzERIeDXzNW5ygzYBvByjTpXmdr1760GAXwUp44ufkvRVrgS/oBijsHqiWcX6Q54UKxYc4bei/nwotEEUEY7/4YSy1IcHHkpkTJrBCw+lzx5pJ9sEQxbdAoGAEHkn9JTMnY33t2XZvUcjWT2MzKfibRl9A9PLxqiv4HdlB5Zc4YJlV2oXsgWkWsDaLsISAlMNMMYNV8gF/53eC+/dkgG4IVvgPkT/dPEpTvW+Ke1IT3tqWGclElCdZHE9RphJJ8A0kfUTirVNylewt+PdD8ITD3yrRt2GGmzPY0M=" ],
- "keyUse" : [ "ENC" ],
- "certificate" : [ "MIICmzCCAYMCBgGQN2wlfTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQwNjIwMjA1MDUyWhcNMzQwNjIwMjA1MjMyWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKxWR9b9Ss5IGlZMKkkx1O6AFZ6aN0TVNl5VCe8AK1XqjnxBjrch3O2ehtvVd8eqmaffLypNw3HaNEv2Ja4wyiR7j2UelyRVw6Xcu/4vNK7RV6fCw3sUTiRQpv1BSVc5j7BMgE22oeCKq8wooJ0zA16xYUN5q7yukzXibmv7vgPD6dphS/7+fceUjRLkve6crEQeYsAUDWOA+KPoTzgZrH3N/QaLC9er9gAXq+SxuYTlXqztu1TbK4fGMAXZiyV0SdthsVd5RL5jonBn39iGTxF+bsxzxsp4G5JSXpKYuMC/u62nx49jwCsrp+bl4yGSFkdQpylni+tvWehrbLdX1XAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAE6H+HxjF6/XOclsHEMVqkQMoHbOb/j+enSaRgLsroX7ir8Xi1mW9HSLReI2H/B8oM/KrVflcGnkE0wD4QR82OR39F/HIbIirwtF96dnBIYs6SzgAUIPrGoBHzAF1yfwcq3utU64yOUKFyS+Lh9LWEULAfMavJJmzYBDSvnzYB/SefOJ/HLLGjs1DLlI72zK9wRisFzlb58Afmmg1I0jAb24NMNNVHK2gY2qIXN4zYcpEKt02dqBnQwyZz3bwzxZXur/+xvNKb+whP4zxNtp6vPiAu9sS+fK+VFCl9tUmaKeDZ+Z1rU1xSJiJ/5XxBmlOdTo5fnGyfWCoQc6pg4OPXM=" ],
- "priority" : [ "100" ],
- "algorithm" : [ "RSA-OAEP" ]
+ "kid" : [ "99b8c5d8-b422-4a80-a89b-2b314e88d878" ],
+ "secret" : [ "ZZ6PFzoCmFp48E0-F3TVEw" ],
+ "priority" : [ "100" ]
}
} ]
},
"internationalizationEnabled" : false,
"supportedLocales" : [ ],
"authenticationFlows" : [ {
- "id" : "28655129-e787-442d-82ec-2175afcdedbe",
+ "id" : "c91487d4-f795-4de6-9b52-44a98ff08b17",
"alias" : "Account verification options",
"description" : "Method with which to verity the existing account",
"providerId" : "basic-flow",
@@ -1285,7 +1285,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "b97ef93b-4707-4427-924c-06b12a9d6b42",
+ "id" : "a2d3a758-1964-4082-b8de-67d214d20b73",
"alias" : "Browser - Conditional OTP",
"description" : "Flow to determine if the OTP is required for the authentication",
"providerId" : "basic-flow",
@@ -1307,7 +1307,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "b404c2a1-97cd-49f8-9ff8-51c33a2a475f",
+ "id" : "6f0f0386-b936-4824-a945-585b427cd239",
"alias" : "Direct Grant - Conditional OTP",
"description" : "Flow to determine if the OTP is required for the authentication",
"providerId" : "basic-flow",
@@ -1329,7 +1329,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "d73479e8-8ecc-4a59-a988-2b70dc635f32",
+ "id" : "d2e29c8c-a3ec-4089-adb5-c6ac6b86cc6d",
"alias" : "First broker login - Conditional OTP",
"description" : "Flow to determine if the OTP is required for the authentication",
"providerId" : "basic-flow",
@@ -1351,7 +1351,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "77e2aa4b-7ac5-4540-bcab-b3cdb874d0e8",
+ "id" : "d0e10cd6-f0c1-44b7-a3bb-82c2af613859",
"alias" : "Handle Existing Account",
"description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider",
"providerId" : "basic-flow",
@@ -1373,7 +1373,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "906e3fe2-9aca-4e2a-8452-207437aa58b2",
+ "id" : "0138758d-c773-4ee1-a96e-7a49c52fac40",
"alias" : "Reset - Conditional OTP",
"description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
"providerId" : "basic-flow",
@@ -1395,7 +1395,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "dfffe646-6381-41c1-984b-daa6ee2c361d",
+ "id" : "707a42fc-9d0f-4c81-84dc-0922d4e0b81f",
"alias" : "User creation or linking",
"description" : "Flow for the existing/non-existing user alternatives",
"providerId" : "basic-flow",
@@ -1418,7 +1418,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "eb8571c5-747d-41c9-860f-11918fd78424",
+ "id" : "779e49d0-6aad-42f8-8f15-b53718635b92",
"alias" : "Verify Existing Account by Re-authentication",
"description" : "Reauthentication of existing account",
"providerId" : "basic-flow",
@@ -1440,7 +1440,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "379aebe8-0bd2-4987-81bc-1445a1c874f2",
+ "id" : "c762e845-dcf7-4109-a2f0-2946a6adc859",
"alias" : "browser",
"description" : "browser based authentication",
"providerId" : "basic-flow",
@@ -1476,7 +1476,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "d1423eee-21e0-4f8e-be0f-3181391271fa",
+ "id" : "d1c1432f-8205-4690-a0aa-84893776141c",
"alias" : "clients",
"description" : "Base authentication for clients",
"providerId" : "client-flow",
@@ -1512,7 +1512,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "265a3aec-eb37-48ca-8dae-343b89704cc6",
+ "id" : "28ab037a-7672-4ea2-bbd7-0a616cb42d01",
"alias" : "direct grant",
"description" : "OpenID Connect Resource Owner Grant",
"providerId" : "basic-flow",
@@ -1541,7 +1541,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "fa1af060-848f-4c0b-87ce-aa2479deb144",
+ "id" : "0a96e97f-e194-4f49-a992-4bc51b07d34f",
"alias" : "docker auth",
"description" : "Used by Docker clients to authenticate against the IDP",
"providerId" : "basic-flow",
@@ -1556,7 +1556,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "479f337c-603f-4b0c-855c-81076a300634",
+ "id" : "977365e9-b7c8-4cc3-88a1-fe556a68e490",
"alias" : "first broker login",
"description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
"providerId" : "basic-flow",
@@ -1579,7 +1579,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "ca92fcc1-d758-482a-9aff-24576d1bd58f",
+ "id" : "310e7c54-e96f-45da-a57d-4b21d490ade9",
"alias" : "forms",
"description" : "Username, password, otp and other auth forms.",
"providerId" : "basic-flow",
@@ -1601,7 +1601,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "b12d71a9-8281-4e29-b964-9c6b0cc9f3f4",
+ "id" : "058a7bad-aa61-4052-af90-0ed63c829723",
"alias" : "registration",
"description" : "registration flow",
"providerId" : "basic-flow",
@@ -1617,7 +1617,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "8dce7cd5-3a30-4a96-b9da-c934040d09f3",
+ "id" : "52d266a5-2e08-47be-939a-a8871ed2a16d",
"alias" : "registration form",
"description" : "registration form",
"providerId" : "form-flow",
@@ -1653,7 +1653,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "f0e9cd6d-b215-42bf-90da-bc6e6f26fe38",
+ "id" : "65663da1-53aa-4a45-aba1-e0ce8c2e7500",
"alias" : "reset credentials",
"description" : "Reset credentials for a user if they forgot their password or something",
"providerId" : "basic-flow",
@@ -1689,7 +1689,7 @@
"userSetupAllowed" : false
} ]
}, {
- "id" : "3ebd8362-d11a-48e4-8ef0-3e03a7defd68",
+ "id" : "150df60a-42f4-415a-b0b1-89a9e9cf76d2",
"alias" : "saml ecp",
"description" : "SAML ECP Profile Authentication Flow",
"providerId" : "basic-flow",
@@ -1705,13 +1705,13 @@
} ]
} ],
"authenticatorConfig" : [ {
- "id" : "56353b42-24a4-4e59-aa2a-b027914d8f28",
+ "id" : "40732755-fbff-4716-9f05-d50581b4b493",
"alias" : "create unique user config",
"config" : {
"require.password.update.after.registration" : "false"
}
}, {
- "id" : "d860c38c-b89b-41e0-a70e-953dd6252f5e",
+ "id" : "3e4cf76d-9d20-46ff-811e-2a7508fa7d68",
"alias" : "review profile config",
"config" : {
"update.profile.on.first.login" : "missing"
diff --git a/src/test/resources/import-files/exported-realm/25.0.5/master-realm.json b/src/test/resources/import-files/exported-realm/25.0.5/master-realm.json
new file mode 100644
index 000000000..b903f8459
--- /dev/null
+++ b/src/test/resources/import-files/exported-realm/25.0.5/master-realm.json
@@ -0,0 +1,1833 @@
+{
+ "id" : "55629008-ce2b-4083-8543-aab9be5c8770",
+ "realm" : "master",
+ "displayName" : "Keycloak",
+ "displayNameHtml" : "Keycloak
",
+ "notBefore" : 0,
+ "defaultSignatureAlgorithm" : "RS256",
+ "revokeRefreshToken" : false,
+ "refreshTokenMaxReuse" : 0,
+ "accessTokenLifespan" : 60,
+ "accessTokenLifespanForImplicitFlow" : 900,
+ "ssoSessionIdleTimeout" : 1800,
+ "ssoSessionMaxLifespan" : 36000,
+ "ssoSessionIdleTimeoutRememberMe" : 0,
+ "ssoSessionMaxLifespanRememberMe" : 0,
+ "offlineSessionIdleTimeout" : 2592000,
+ "offlineSessionMaxLifespanEnabled" : false,
+ "offlineSessionMaxLifespan" : 5184000,
+ "clientSessionIdleTimeout" : 0,
+ "clientSessionMaxLifespan" : 0,
+ "clientOfflineSessionIdleTimeout" : 0,
+ "clientOfflineSessionMaxLifespan" : 0,
+ "accessCodeLifespan" : 60,
+ "accessCodeLifespanUserAction" : 300,
+ "accessCodeLifespanLogin" : 1800,
+ "actionTokenGeneratedByAdminLifespan" : 43200,
+ "actionTokenGeneratedByUserLifespan" : 300,
+ "oauth2DeviceCodeLifespan" : 600,
+ "oauth2DevicePollingInterval" : 5,
+ "enabled" : true,
+ "sslRequired" : "external",
+ "registrationAllowed" : false,
+ "registrationEmailAsUsername" : false,
+ "rememberMe" : false,
+ "verifyEmail" : false,
+ "loginWithEmailAllowed" : true,
+ "duplicateEmailsAllowed" : false,
+ "resetPasswordAllowed" : false,
+ "editUsernameAllowed" : false,
+ "bruteForceProtected" : false,
+ "permanentLockout" : false,
+ "maxTemporaryLockouts" : 0,
+ "maxFailureWaitSeconds" : 900,
+ "minimumQuickLoginWaitSeconds" : 60,
+ "waitIncrementSeconds" : 60,
+ "quickLoginCheckMilliSeconds" : 1000,
+ "maxDeltaTimeSeconds" : 43200,
+ "failureFactor" : 30,
+ "roles" : {
+ "realm" : [ {
+ "id" : "2d17c8ae-3af1-4c17-892c-394b5dfffb8c",
+ "name" : "uma_authorization",
+ "description" : "${role_uma_authorization}",
+ "composite" : false,
+ "clientRole" : false,
+ "containerId" : "55629008-ce2b-4083-8543-aab9be5c8770",
+ "attributes" : { }
+ }, {
+ "id" : "b6f32281-43f1-4c5c-9175-a33c0b098198",
+ "name" : "offline_access",
+ "description" : "${role_offline-access}",
+ "composite" : false,
+ "clientRole" : false,
+ "containerId" : "55629008-ce2b-4083-8543-aab9be5c8770",
+ "attributes" : { }
+ }, {
+ "id" : "6c3542f4-d34e-46c1-82c5-550fb579a747",
+ "name" : "create-realm",
+ "description" : "${role_create-realm}",
+ "composite" : false,
+ "clientRole" : false,
+ "containerId" : "55629008-ce2b-4083-8543-aab9be5c8770",
+ "attributes" : { }
+ }, {
+ "id" : "305c2c19-794e-49af-973c-b634e0f80e7f",
+ "name" : "admin",
+ "description" : "${role_admin}",
+ "composite" : true,
+ "composites" : {
+ "realm" : [ "create-realm" ],
+ "client" : {
+ "master-realm" : [ "query-users", "create-client", "query-clients", "view-identity-providers", "query-groups", "manage-authorization", "manage-identity-providers", "impersonation", "manage-users", "view-realm", "manage-events", "manage-realm", "query-realms", "view-authorization", "manage-clients", "view-events", "view-users", "view-clients" ]
+ }
+ },
+ "clientRole" : false,
+ "containerId" : "55629008-ce2b-4083-8543-aab9be5c8770",
+ "attributes" : { }
+ }, {
+ "id" : "3dab2fbc-247f-4615-a0fe-f89c382f1c61",
+ "name" : "default-roles-master",
+ "description" : "${role_default-roles}",
+ "composite" : true,
+ "composites" : {
+ "realm" : [ "offline_access", "uma_authorization" ],
+ "client" : {
+ "account" : [ "manage-account", "view-profile" ]
+ }
+ },
+ "clientRole" : false,
+ "containerId" : "55629008-ce2b-4083-8543-aab9be5c8770",
+ "attributes" : { }
+ } ],
+ "client" : {
+ "security-admin-console" : [ ],
+ "admin-cli" : [ ],
+ "account-console" : [ ],
+ "broker" : [ {
+ "id" : "3d6c30c9-4196-490f-8861-18a520071589",
+ "name" : "read-token",
+ "description" : "${role_read-token}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "fc8c7b1a-a320-47c3-941c-b2f2526bbb1c",
+ "attributes" : { }
+ } ],
+ "master-realm" : [ {
+ "id" : "a8637f4c-dae7-4edf-b7cd-3b9bcb54b14b",
+ "name" : "query-users",
+ "description" : "${role_query-users}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "87eb352d-2784-47aa-8587-228cb3c3b389",
+ "name" : "create-client",
+ "description" : "${role_create-client}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "4dd68b4c-4f66-411f-95af-1468b0061dc6",
+ "name" : "query-clients",
+ "description" : "${role_query-clients}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "52d635b5-0654-4ddd-82c7-1462cd0f6348",
+ "name" : "view-identity-providers",
+ "description" : "${role_view-identity-providers}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "b4209cfd-e1c6-43d8-917e-a822ec23a4de",
+ "name" : "query-groups",
+ "description" : "${role_query-groups}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "15c8fec9-1610-4ee0-8402-ef7e123e789f",
+ "name" : "manage-authorization",
+ "description" : "${role_manage-authorization}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "6d54aff9-a6a0-4209-bbd1-aac3be464ca0",
+ "name" : "manage-identity-providers",
+ "description" : "${role_manage-identity-providers}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "30a6d10c-e297-44f8-8c4c-b0dde377ffd0",
+ "name" : "impersonation",
+ "description" : "${role_impersonation}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "ac2e28ec-7f86-425a-b96c-f9641cd0198e",
+ "name" : "manage-users",
+ "description" : "${role_manage-users}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "b4cbdffb-4242-481c-92e4-63fcee6456e1",
+ "name" : "view-realm",
+ "description" : "${role_view-realm}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "84f688fb-4ff5-4761-9813-0ff3853de194",
+ "name" : "manage-events",
+ "description" : "${role_manage-events}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "a87c1cf9-aeff-49da-ae0d-d9f4868f1483",
+ "name" : "manage-realm",
+ "description" : "${role_manage-realm}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "1c44abc2-96d1-4bb5-b92d-268590ee2cd9",
+ "name" : "query-realms",
+ "description" : "${role_query-realms}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "901b6ece-ce03-4bfe-8bd6-4402c04128be",
+ "name" : "manage-clients",
+ "description" : "${role_manage-clients}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "31774f68-8358-424b-8f7f-33056491eb91",
+ "name" : "view-authorization",
+ "description" : "${role_view-authorization}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "a595b1f3-6971-4299-a8f4-c45f37b300f9",
+ "name" : "view-events",
+ "description" : "${role_view-events}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "477a4a7c-d685-4fab-916e-ba4e81d8a5d3",
+ "name" : "view-users",
+ "description" : "${role_view-users}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "master-realm" : [ "query-users", "query-groups" ]
+ }
+ },
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ }, {
+ "id" : "ca550468-dabe-440b-993a-cdbaafcf3ba3",
+ "name" : "view-clients",
+ "description" : "${role_view-clients}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "master-realm" : [ "query-clients" ]
+ }
+ },
+ "clientRole" : true,
+ "containerId" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "attributes" : { }
+ } ],
+ "account" : [ {
+ "id" : "61a4806b-24fe-4fb6-ade8-ae4297c9eb0e",
+ "name" : "manage-account-links",
+ "description" : "${role_manage-account-links}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "35b8eef9-8716-4907-be74-94dd7310e79d",
+ "attributes" : { }
+ }, {
+ "id" : "f967a9a9-239e-46c0-ad99-a02461fe8ba3",
+ "name" : "delete-account",
+ "description" : "${role_delete-account}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "35b8eef9-8716-4907-be74-94dd7310e79d",
+ "attributes" : { }
+ }, {
+ "id" : "83b4bbe3-3590-4bab-9000-40c30cd74b8a",
+ "name" : "manage-account",
+ "description" : "${role_manage-account}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "account" : [ "manage-account-links" ]
+ }
+ },
+ "clientRole" : true,
+ "containerId" : "35b8eef9-8716-4907-be74-94dd7310e79d",
+ "attributes" : { }
+ }, {
+ "id" : "05423878-1b36-4acd-be69-deb4d84a6d88",
+ "name" : "view-applications",
+ "description" : "${role_view-applications}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "35b8eef9-8716-4907-be74-94dd7310e79d",
+ "attributes" : { }
+ }, {
+ "id" : "895bf952-95c3-4399-a9cc-c0267dd85615",
+ "name" : "view-consent",
+ "description" : "${role_view-consent}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "35b8eef9-8716-4907-be74-94dd7310e79d",
+ "attributes" : { }
+ }, {
+ "id" : "65a7eff2-0043-408a-b0a8-11240b65af3b",
+ "name" : "view-groups",
+ "description" : "${role_view-groups}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "35b8eef9-8716-4907-be74-94dd7310e79d",
+ "attributes" : { }
+ }, {
+ "id" : "8dec7ad0-523e-437f-8719-6430a9dfc5ba",
+ "name" : "view-profile",
+ "description" : "${role_view-profile}",
+ "composite" : false,
+ "clientRole" : true,
+ "containerId" : "35b8eef9-8716-4907-be74-94dd7310e79d",
+ "attributes" : { }
+ }, {
+ "id" : "9338a13f-baeb-44a5-a45c-140508cebcbf",
+ "name" : "manage-consent",
+ "description" : "${role_manage-consent}",
+ "composite" : true,
+ "composites" : {
+ "client" : {
+ "account" : [ "view-consent" ]
+ }
+ },
+ "clientRole" : true,
+ "containerId" : "35b8eef9-8716-4907-be74-94dd7310e79d",
+ "attributes" : { }
+ } ]
+ }
+ },
+ "groups" : [ ],
+ "defaultRole" : {
+ "id" : "3dab2fbc-247f-4615-a0fe-f89c382f1c61",
+ "name" : "default-roles-master",
+ "description" : "${role_default-roles}",
+ "composite" : true,
+ "clientRole" : false,
+ "containerId" : "55629008-ce2b-4083-8543-aab9be5c8770"
+ },
+ "requiredCredentials" : [ "password" ],
+ "otpPolicyType" : "totp",
+ "otpPolicyAlgorithm" : "HmacSHA1",
+ "otpPolicyInitialCounter" : 0,
+ "otpPolicyDigits" : 6,
+ "otpPolicyLookAheadWindow" : 1,
+ "otpPolicyPeriod" : 30,
+ "otpPolicyCodeReusable" : false,
+ "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName" ],
+ "localizationTexts" : { },
+ "webAuthnPolicyRpEntityName" : "keycloak",
+ "webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
+ "webAuthnPolicyRpId" : "",
+ "webAuthnPolicyAttestationConveyancePreference" : "not specified",
+ "webAuthnPolicyAuthenticatorAttachment" : "not specified",
+ "webAuthnPolicyRequireResidentKey" : "not specified",
+ "webAuthnPolicyUserVerificationRequirement" : "not specified",
+ "webAuthnPolicyCreateTimeout" : 0,
+ "webAuthnPolicyAvoidSameAuthenticatorRegister" : false,
+ "webAuthnPolicyAcceptableAaguids" : [ ],
+ "webAuthnPolicyExtraOrigins" : [ ],
+ "webAuthnPolicyPasswordlessRpEntityName" : "keycloak",
+ "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ],
+ "webAuthnPolicyPasswordlessRpId" : "",
+ "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified",
+ "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified",
+ "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified",
+ "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified",
+ "webAuthnPolicyPasswordlessCreateTimeout" : 0,
+ "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false,
+ "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ],
+ "webAuthnPolicyPasswordlessExtraOrigins" : [ ],
+ "scopeMappings" : [ {
+ "clientScope" : "offline_access",
+ "roles" : [ "offline_access" ]
+ } ],
+ "clientScopeMappings" : {
+ "account" : [ {
+ "client" : "account-console",
+ "roles" : [ "manage-account", "view-groups" ]
+ } ]
+ },
+ "clients" : [ {
+ "id" : "35b8eef9-8716-4907-be74-94dd7310e79d",
+ "clientId" : "account",
+ "name" : "${client_account}",
+ "rootUrl" : "${authBaseUrl}",
+ "baseUrl" : "/realms/master/account/",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ "/realms/master/account/*" ],
+ "webOrigins" : [ ],
+ "notBefore" : 0,
+ "bearerOnly" : false,
+ "consentRequired" : false,
+ "standardFlowEnabled" : true,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : false,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : true,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "post.logout.redirect.uris" : "+"
+ },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : false,
+ "nodeReRegistrationTimeout" : 0,
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+ }, {
+ "id" : "acc8caf3-a610-45cd-b2f1-ce4245274289",
+ "clientId" : "account-console",
+ "name" : "${client_account-console}",
+ "rootUrl" : "${authBaseUrl}",
+ "baseUrl" : "/realms/master/account/",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ "/realms/master/account/*" ],
+ "webOrigins" : [ ],
+ "notBefore" : 0,
+ "bearerOnly" : false,
+ "consentRequired" : false,
+ "standardFlowEnabled" : true,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : false,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : true,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "post.logout.redirect.uris" : "+",
+ "pkce.code.challenge.method" : "S256"
+ },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : false,
+ "nodeReRegistrationTimeout" : 0,
+ "protocolMappers" : [ {
+ "id" : "d137a637-7423-4f2c-86ef-0e158a3ce338",
+ "name" : "audience resolve",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-audience-resolve-mapper",
+ "consentRequired" : false,
+ "config" : { }
+ } ],
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+ }, {
+ "id" : "5f39526a-b61e-496b-b08e-609cc0357a9b",
+ "clientId" : "admin-cli",
+ "name" : "${client_admin-cli}",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ ],
+ "webOrigins" : [ ],
+ "notBefore" : 0,
+ "bearerOnly" : false,
+ "consentRequired" : false,
+ "standardFlowEnabled" : false,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : true,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : true,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : { },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : false,
+ "nodeReRegistrationTimeout" : 0,
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+ }, {
+ "id" : "fc8c7b1a-a320-47c3-941c-b2f2526bbb1c",
+ "clientId" : "broker",
+ "name" : "${client_broker}",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ ],
+ "webOrigins" : [ ],
+ "notBefore" : 0,
+ "bearerOnly" : true,
+ "consentRequired" : false,
+ "standardFlowEnabled" : true,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : false,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : false,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : { },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : false,
+ "nodeReRegistrationTimeout" : 0,
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+ }, {
+ "id" : "2e87bbcd-3d6d-4e09-8115-9e5f45b96c87",
+ "clientId" : "master-realm",
+ "name" : "master Realm",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ ],
+ "webOrigins" : [ ],
+ "notBefore" : 0,
+ "bearerOnly" : true,
+ "consentRequired" : false,
+ "standardFlowEnabled" : true,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : false,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : false,
+ "frontchannelLogout" : false,
+ "attributes" : { },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : false,
+ "nodeReRegistrationTimeout" : 0,
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+ }, {
+ "id" : "f62d771b-69ba-4fb6-a438-38dd828a820f",
+ "clientId" : "security-admin-console",
+ "name" : "${client_security-admin-console}",
+ "rootUrl" : "${authAdminUrl}",
+ "baseUrl" : "/admin/master/console/",
+ "surrogateAuthRequired" : false,
+ "enabled" : true,
+ "alwaysDisplayInConsole" : false,
+ "clientAuthenticatorType" : "client-secret",
+ "redirectUris" : [ "/admin/master/console/*" ],
+ "webOrigins" : [ "+" ],
+ "notBefore" : 0,
+ "bearerOnly" : false,
+ "consentRequired" : false,
+ "standardFlowEnabled" : true,
+ "implicitFlowEnabled" : false,
+ "directAccessGrantsEnabled" : false,
+ "serviceAccountsEnabled" : false,
+ "publicClient" : true,
+ "frontchannelLogout" : false,
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "post.logout.redirect.uris" : "+",
+ "pkce.code.challenge.method" : "S256"
+ },
+ "authenticationFlowBindingOverrides" : { },
+ "fullScopeAllowed" : false,
+ "nodeReRegistrationTimeout" : 0,
+ "protocolMappers" : [ {
+ "id" : "c7fc85a2-9902-4141-9292-198e38482be9",
+ "name" : "locale",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "locale",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "locale",
+ "jsonType.label" : "String"
+ }
+ } ],
+ "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ],
+ "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+ } ],
+ "clientScopes" : [ {
+ "id" : "2d20ac87-c4c9-4669-8817-72d762740765",
+ "name" : "offline_access",
+ "description" : "OpenID Connect built-in scope: offline_access",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "consent.screen.text" : "${offlineAccessScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ }
+ }, {
+ "id" : "c971abb0-a8e4-4f02-912a-225cfcd9b459",
+ "name" : "acr",
+ "description" : "OpenID Connect scope for add acr (authentication context class reference) to the token",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "false",
+ "display.on.consent.screen" : "false"
+ },
+ "protocolMappers" : [ {
+ "id" : "7ee61ec6-ad2a-475b-9a24-85d3c2e7cb3c",
+ "name" : "acr loa level",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-acr-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "id.token.claim" : "true",
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true"
+ }
+ } ]
+ }, {
+ "id" : "9ad8bb00-9914-40d3-b5d7-5d8291e9e443",
+ "name" : "roles",
+ "description" : "OpenID Connect scope for add user roles to the access token",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "false",
+ "consent.screen.text" : "${rolesScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "4de0a385-cbf0-469f-9a5f-392c05c82140",
+ "name" : "client roles",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-client-role-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "user.attribute" : "foo",
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "resource_access.${client_id}.roles",
+ "jsonType.label" : "String",
+ "multivalued" : "true"
+ }
+ }, {
+ "id" : "6243d0e8-3408-4ddb-abfc-11b695e7b2d0",
+ "name" : "realm roles",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "user.attribute" : "foo",
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "realm_access.roles",
+ "jsonType.label" : "String",
+ "multivalued" : "true"
+ }
+ }, {
+ "id" : "6acd19c0-2966-4b14-b3a3-23d12f93a57a",
+ "name" : "audience resolve",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-audience-resolve-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true"
+ }
+ } ]
+ }, {
+ "id" : "94ca65f7-c8e1-4e9d-9047-a75eba57f74b",
+ "name" : "role_list",
+ "description" : "SAML role list",
+ "protocol" : "saml",
+ "attributes" : {
+ "consent.screen.text" : "${samlRoleListScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "62962673-ce81-4253-87b4-7f46a3afd696",
+ "name" : "role list",
+ "protocol" : "saml",
+ "protocolMapper" : "saml-role-list-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "single" : "false",
+ "attribute.nameformat" : "Basic",
+ "attribute.name" : "Role"
+ }
+ } ]
+ }, {
+ "id" : "cdf4b8ff-6935-4913-afb7-1837731701f3",
+ "name" : "email",
+ "description" : "OpenID Connect built-in scope: email",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${emailScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "b3338a00-7e5a-4fbd-aee1-bff1f817007d",
+ "name" : "email verified",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-property-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "emailVerified",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "email_verified",
+ "jsonType.label" : "boolean"
+ }
+ }, {
+ "id" : "1783cd75-645d-4f2b-a48c-bf2f6d707262",
+ "name" : "email",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "email",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "email",
+ "jsonType.label" : "String"
+ }
+ } ]
+ }, {
+ "id" : "46405ff1-0e62-4222-8f33-4627072f3b26",
+ "name" : "web-origins",
+ "description" : "OpenID Connect scope for add allowed web origins to the access token",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "false",
+ "consent.screen.text" : "",
+ "display.on.consent.screen" : "false"
+ },
+ "protocolMappers" : [ {
+ "id" : "b50eff38-2442-42f7-aef2-3e01effa005a",
+ "name" : "allowed web origins",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-allowed-origins-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true"
+ }
+ } ]
+ }, {
+ "id" : "06f6c19f-6045-4647-92da-a9cd0497a4f8",
+ "name" : "basic",
+ "description" : "OpenID Connect scope for add all basic claims to the token",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "false",
+ "display.on.consent.screen" : "false"
+ },
+ "protocolMappers" : [ {
+ "id" : "838ea479-de74-4cd3-8e9c-21f42b3b1b46",
+ "name" : "auth_time",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "user.session.note" : "AUTH_TIME",
+ "id.token.claim" : "true",
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "auth_time",
+ "jsonType.label" : "long"
+ }
+ }, {
+ "id" : "a8fa5167-2d4b-4be3-aefd-1cd42d3abbc3",
+ "name" : "sub",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-sub-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true"
+ }
+ } ]
+ }, {
+ "id" : "3f45efd8-d12b-4a45-b8f7-9f7cec39039f",
+ "name" : "microprofile-jwt",
+ "description" : "Microprofile - JWT built-in scope",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "display.on.consent.screen" : "false"
+ },
+ "protocolMappers" : [ {
+ "id" : "cf4f3daf-4f05-46f5-bed7-6de6fc3a588a",
+ "name" : "groups",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "multivalued" : "true",
+ "user.attribute" : "foo",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "groups",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "83afe61e-c2d6-45ad-b3bb-6f1e76dfb1ce",
+ "name" : "upn",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "username",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "upn",
+ "jsonType.label" : "String"
+ }
+ } ]
+ }, {
+ "id" : "b39d8d21-3b25-4817-a9e7-67f8e059d5a7",
+ "name" : "address",
+ "description" : "OpenID Connect built-in scope: address",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${addressScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "5d68a21b-a4b2-4a36-a97b-d342324a7b2c",
+ "name" : "address",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-address-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "user.attribute.formatted" : "formatted",
+ "user.attribute.country" : "country",
+ "introspection.token.claim" : "true",
+ "user.attribute.postal_code" : "postal_code",
+ "userinfo.token.claim" : "true",
+ "user.attribute.street" : "street",
+ "id.token.claim" : "true",
+ "user.attribute.region" : "region",
+ "access.token.claim" : "true",
+ "user.attribute.locality" : "locality"
+ }
+ } ]
+ }, {
+ "id" : "916bb27b-3294-4881-b301-14dd75538a71",
+ "name" : "profile",
+ "description" : "OpenID Connect built-in scope: profile",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${profileScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "62e2c9bc-fb68-43dd-9f14-fd1efd689b86",
+ "name" : "family name",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "lastName",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "family_name",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "b48b6d86-81cb-4608-8809-17b38c6480a8",
+ "name" : "zoneinfo",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "zoneinfo",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "zoneinfo",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "3456d440-c1c4-4cb4-951a-39a0728506d0",
+ "name" : "nickname",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "nickname",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "nickname",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "c9c4d8b0-a041-4ecf-b23e-42f3b2694e26",
+ "name" : "profile",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "profile",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "profile",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "16a90a31-a90f-4c0a-85ce-04bceca33f0a",
+ "name" : "picture",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "picture",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "picture",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "522bd07d-8996-4b9d-8e58-6a8ebbfdeef7",
+ "name" : "middle name",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "middleName",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "middle_name",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "5458c27e-5edd-4bfa-90f7-7153cb0f8e03",
+ "name" : "locale",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "locale",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "locale",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "5754217d-7b38-4e40-bad6-c80e94f638c3",
+ "name" : "given name",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "firstName",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "given_name",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "b801307d-ed2c-4cef-96f2-1e598520b3d5",
+ "name" : "full name",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-full-name-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "id.token.claim" : "true",
+ "introspection.token.claim" : "true",
+ "access.token.claim" : "true",
+ "userinfo.token.claim" : "true"
+ }
+ }, {
+ "id" : "0c9d3061-9e9d-4f67-9e24-03d6d5c30ceb",
+ "name" : "birthdate",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "birthdate",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "birthdate",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "9f451040-74c5-4c2a-97e7-2f9445340b5c",
+ "name" : "username",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "username",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "preferred_username",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "9b4231f0-e0ed-49c5-97f9-d1420b5642fb",
+ "name" : "updated at",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "updatedAt",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "updated_at",
+ "jsonType.label" : "long"
+ }
+ }, {
+ "id" : "d9870bab-1f80-4f4a-b3f8-967653dc30c1",
+ "name" : "website",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "website",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "website",
+ "jsonType.label" : "String"
+ }
+ }, {
+ "id" : "4651b46f-49d0-4e32-84ca-26fc14b6d583",
+ "name" : "gender",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "gender",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "gender",
+ "jsonType.label" : "String"
+ }
+ } ]
+ }, {
+ "id" : "2c886135-ef41-45ca-ba5e-096908a7fabd",
+ "name" : "phone",
+ "description" : "OpenID Connect built-in scope: phone",
+ "protocol" : "openid-connect",
+ "attributes" : {
+ "include.in.token.scope" : "true",
+ "consent.screen.text" : "${phoneScopeConsentText}",
+ "display.on.consent.screen" : "true"
+ },
+ "protocolMappers" : [ {
+ "id" : "226d6df9-bd98-497b-a50a-5fb47900b3d2",
+ "name" : "phone number verified",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "phoneNumberVerified",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "phone_number_verified",
+ "jsonType.label" : "boolean"
+ }
+ }, {
+ "id" : "d0a583c1-2b9d-4104-b680-97a508d9bfc3",
+ "name" : "phone number",
+ "protocol" : "openid-connect",
+ "protocolMapper" : "oidc-usermodel-attribute-mapper",
+ "consentRequired" : false,
+ "config" : {
+ "introspection.token.claim" : "true",
+ "userinfo.token.claim" : "true",
+ "user.attribute" : "phoneNumber",
+ "id.token.claim" : "true",
+ "access.token.claim" : "true",
+ "claim.name" : "phone_number",
+ "jsonType.label" : "String"
+ }
+ } ]
+ } ],
+ "defaultDefaultClientScopes" : [ "role_list", "profile", "email", "roles", "web-origins", "acr", "basic" ],
+ "defaultOptionalClientScopes" : [ "offline_access", "address", "phone", "microprofile-jwt" ],
+ "browserSecurityHeaders" : {
+ "contentSecurityPolicyReportOnly" : "",
+ "xContentTypeOptions" : "nosniff",
+ "referrerPolicy" : "no-referrer",
+ "xRobotsTag" : "none",
+ "xFrameOptions" : "SAMEORIGIN",
+ "xXSSProtection" : "1; mode=block",
+ "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+ "strictTransportSecurity" : "max-age=31536000; includeSubDomains"
+ },
+ "smtpServer" : { },
+ "eventsEnabled" : false,
+ "eventsListeners" : [ "jboss-logging" ],
+ "enabledEventTypes" : [ ],
+ "adminEventsEnabled" : false,
+ "adminEventsDetailsEnabled" : false,
+ "identityProviders" : [ ],
+ "identityProviderMappers" : [ ],
+ "components" : {
+ "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ {
+ "id" : "87057623-2bae-4d00-b2b5-3a51a77575cf",
+ "name" : "Max Clients Limit",
+ "providerId" : "max-clients",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : {
+ "max-clients" : [ "200" ]
+ }
+ }, {
+ "id" : "05f11c22-2fb9-4fcd-a1e1-0ded5b9de360",
+ "name" : "Allowed Client Scopes",
+ "providerId" : "allowed-client-templates",
+ "subType" : "authenticated",
+ "subComponents" : { },
+ "config" : {
+ "allow-default-scopes" : [ "true" ]
+ }
+ }, {
+ "id" : "da12dadc-2535-4ad5-86e1-d1ef956a0364",
+ "name" : "Allowed Client Scopes",
+ "providerId" : "allowed-client-templates",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : {
+ "allow-default-scopes" : [ "true" ]
+ }
+ }, {
+ "id" : "5cc8d47e-038c-4532-a180-7a9a8cd24414",
+ "name" : "Allowed Protocol Mapper Types",
+ "providerId" : "allowed-protocol-mappers",
+ "subType" : "authenticated",
+ "subComponents" : { },
+ "config" : {
+ "allowed-protocol-mapper-types" : [ "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "saml-role-list-mapper", "saml-user-property-mapper" ]
+ }
+ }, {
+ "id" : "c5f68155-3167-45c8-9f74-841bf10b1b06",
+ "name" : "Trusted Hosts",
+ "providerId" : "trusted-hosts",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : {
+ "host-sending-registration-request-must-match" : [ "true" ],
+ "client-uris-must-match" : [ "true" ]
+ }
+ }, {
+ "id" : "cd1ca8c0-a84e-41e0-8274-b361b55ffb73",
+ "name" : "Consent Required",
+ "providerId" : "consent-required",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : { }
+ }, {
+ "id" : "77d72357-68df-434a-8be3-3e38125c7a5b",
+ "name" : "Full Scope Disabled",
+ "providerId" : "scope",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : { }
+ }, {
+ "id" : "d9fbfcdd-60c8-4945-8cf2-66b63d59ab4b",
+ "name" : "Allowed Protocol Mapper Types",
+ "providerId" : "allowed-protocol-mappers",
+ "subType" : "anonymous",
+ "subComponents" : { },
+ "config" : {
+ "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper" ]
+ }
+ } ],
+ "org.keycloak.userprofile.UserProfileProvider" : [ {
+ "id" : "94e6d532-7947-4f4d-a299-bb8ba6abbfbd",
+ "providerId" : "declarative-user-profile",
+ "subComponents" : { },
+ "config" : {
+ "kc.user.profile.config" : [ "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}]}" ]
+ }
+ } ],
+ "org.keycloak.keys.KeyProvider" : [ {
+ "id" : "e30b9bb6-81cf-4924-9c4c-6e8ca8422bf4",
+ "name" : "hmac-generated-hs512",
+ "providerId" : "hmac-generated",
+ "subComponents" : { },
+ "config" : {
+ "kid" : [ "20ae767e-f05d-41af-bf73-3de8f7b88150" ],
+ "secret" : [ "qIK-SLxIZhBtMbvp1WK6SdDwy5iFPO2NPQoShzdwE324Vlb4tzD5l5XTK6-23nDycjeZ3FV_jT0VQzUzD_yl4yKwe6bDMQJKKUW1uUe0zITSrYoEMxrLzVUO0tnKHVc62GuDJI8ejkg_qQuUOV2DhUdxuukaHCRdsXp6h5PSQKc" ],
+ "priority" : [ "100" ],
+ "algorithm" : [ "HS512" ]
+ }
+ }, {
+ "id" : "22177e0b-0bf0-494d-a1c1-23acfc99f87b",
+ "name" : "aes-generated",
+ "providerId" : "aes-generated",
+ "subComponents" : { },
+ "config" : {
+ "kid" : [ "7ed63787-e3ff-4485-bce2-ae75ce554674" ],
+ "secret" : [ "VH4-cDoW7bSHGmmrLwHB-A" ],
+ "priority" : [ "100" ]
+ }
+ }, {
+ "id" : "8ac14947-ed9f-4f23-bc61-fee97a322fae",
+ "name" : "rsa-generated",
+ "providerId" : "rsa-generated",
+ "subComponents" : { },
+ "config" : {
+ "privateKey" : [ "MIIEpAIBAAKCAQEAxPUr2W2/HjVHzYG4QTHT2h2YJEfXtQd/YkfXPtlhKgSPOKiKbsyJHek3ZvgoMwNkNj6EdB85DboIWlEkZUd6BD7EU98DjaIGfK1U2oqiRM6VA8W0SN+on+mkhUge8hDRC45yaTibc8ngzDzFj6W0zdGS5+HULGtNBO5kxzr3Iq3mSlHMvTBW/EHxeDThBOrUbwcf6CE7oY01xKjsid8H3ujHTqG63WWmF4nycfnxgzwo1bNspmBLkUVXN5x5p2WZxMkV3bPJ3XRZsNcKnrXbnvLV3RRSHx96nYMSHncyyZv/emhiRey0au3X4uCWh944O6VQQgG1tBMTA1ruNZ+7yQIDAQABAoIBAAY1Geww3sijcj9iWr3HRb+GlkByeTRt55Bf5kNHU54g5aip+y7xyFKGgqX+pTmyXiqtfrwwLbqmhdPe4dBFV+2hUsu36CNDG4Q7bES1ANc9UYn8Zam0Ttq3YOWId902NXhxRV7Wl2OnVavqMGnOFaw08jXXsrmxqgxBPTDgRWC03x/tI/qSsPP/zj4QfcmIFBjjXyg6+07z07kILBI+0pJNuk0wodA2KyD7FuakLgbgQxHM0tB9ob/cuOY11REuQuis8MN0pdP2GEttWxcDhhVlEGuQu+Em5tnxKfM3Z8Q2nJfyCYhBhSvBRNCqVFMp/TSNn9ncw0m3lWbIgVCsFYcCgYEA/LVvUwg30yWbDiqmuPClCpKFfjzQgaHQ/vSvU89xdDj7A6rjKig8MXB2EXk4XN/V66ZcTt4Q041ICY4yGWlfCdxqcaaAjL/iHOKc6/1Wg2LycAsRlC0jejaCHMDdPYNsgbS1DiswZoiB06/wDmhqkRjo60ILRmWTPgyzWcFUvDMCgYEAx4Xa3WQUBtIItZW4z4VC7ALetJ6YHJomGZRvNCkO+HVeadrIS1HzELzdPEmeHNeqqUD0AukJmSuncR4D54WvS+8Ux7zRyTebv87zuBXc4oAmmC+w4sUVOR/r9r5qzPqI4GwTMxmNNzsrzmqx8Vl6q/bR6P+jf+rOBh9heqcPLBMCgYAEywAoiABfDdiKBT8SROYsdCj6AvdFbidDnqpwoX+aX7ZLFIOoegjiOyrSHAV4pXouNQKNMGMLUCOsorjKiJgX3MlcDHdltAH64EVvqGdqqIbGnz8fG1gP6la/at0HXKXDNAU3FpSdbTthI3YfH9XdmKZaR+9kz2pig+Um76bGxwKBgQCPasP7x2gtzuO7wrdpU5zbEOUMZ8NnK9afJHcawzijl5oZ9M1sdqeFLHzKTRB+IvflWW8MeH4Rv7NIOA8OaKWsq1oAiNUzEem+YgAGHpD7rqoPUpiPKKMswKlYX19dn+iriIP0gzVisgG3CjKGDY+D9JLGLJtV423cMMpc46CgSQKBgQC7qB0JWkQVWMvYmXCJugggZ7ywN6pbpWJHmTIHWcfT9KO2xi6YSBV0Jc7RwiCmci71qUfr8leAW9HVEES50eMv2Ney+jPmJXwkTYI9/EJGQpO8AUiEpElGpxB0ZvGf3CCFZ0+W5xB2ZYA78+y/Zbx+TrWNzq3HTTL3nxWUbifpxw==" ],
+ "keyUse" : [ "SIG" ],
+ "certificate" : [ "MIICmzCCAYMCBgGSDEPEojANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQwOTE5MjE0ODQwWhcNMzQwOTE5MjE1MDIwWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDE9SvZbb8eNUfNgbhBMdPaHZgkR9e1B39iR9c+2WEqBI84qIpuzIkd6Tdm+CgzA2Q2PoR0HzkNughaUSRlR3oEPsRT3wONogZ8rVTaiqJEzpUDxbRI36if6aSFSB7yENELjnJpOJtzyeDMPMWPpbTN0ZLn4dQsa00E7mTHOvcireZKUcy9MFb8QfF4NOEE6tRvBx/oITuhjTXEqOyJ3wfe6MdOobrdZaYXifJx+fGDPCjVs2ymYEuRRVc3nHmnZZnEyRXds8nddFmw1wqetdue8tXdFFIfH3qdgxIedzLJm/96aGJF7LRq7dfi4JaH3jg7pVBCAbW0ExMDWu41n7vJAgMBAAEwDQYJKoZIhvcNAQELBQADggEBABd7Xf3EmGEfGiXKSQeWeuQsvogVcaIp9qHcCxHbkABGgSL+I04wAcigLsV774eMTWlwugjet/u4SE5NN+vh0rXdcKsd3o6co4BkA7GzN0vyCVN8sIKtwnu6wzl66ukqhbLiZwUapa7Dbz+kHJha7rpKkOF5i2p05x9+40eQpgP/vGgfuQuWW3BPMPJeG6Mihj11kATWCIEogAWDwcY69MC6zsMsysAP+gxa9R5HkyvA9xsy7J1odo9MNRPUGvrooehBD9StkG3vljf2hSiflhkXI9SLKpWGsrZf9uVzZMI2NEpe6M541YtFAiZID3GlbQ0R51kD2yMgy0mITeLMpHs=" ],
+ "priority" : [ "100" ]
+ }
+ }, {
+ "id" : "86cc40cb-4918-419f-832f-20eb0b7b71ac",
+ "name" : "rsa-enc-generated",
+ "providerId" : "rsa-enc-generated",
+ "subComponents" : { },
+ "config" : {
+ "privateKey" : [ "MIIEpQIBAAKCAQEA4W5uNBxDjiYxBlU/i+tSUl+mDDtGzwYoM1HbEu2SynzdvsUp8jNdvAiSOw53DMz2sfjo0FYo6p2nlCVUwcMm4CseURBsvkdqf5anXkxkPWQ/vUfrb53w68XZ/yElv77MxOzzH6kv1USg7WgO15LULoK32UNk+ppNYqfXlH9v8aCYyFnI8Q35G1tR5PPqKcgI6Zuvr+WK6DjATe0Ce+jqpJ1yV7uDIrR1W6ChIAdaOrU7h+rVyLxRg4Vc32N+X8UT1EQIj2ns5Txy7cCLmW3rT1dHbzat4LKl6WuXNMm/WtkswaSzWMrqsOwKr/cwxRj6JZtyLEF0wei9ss9YS/P0uwIDAQABAoIBABFuxL7q4J6BfZELzpo3XGpaUzDm9JbV1w4A6nwQOyXFejBidtfv+POthgFjIPmwb/NbWEWkJA3gmzDtohxJxxvWucVzC7W7OBUdxVuZdLb6paMxiJddE2BoMG92VMD7NEKWQEbWgohvgjJZtaweAqKGIUl/2LM4c3uJlzY4lKOOrpkA+3KaATI2hmtcZuhzr+8JvaZbt1eX4SYCKCC1/uU0vJ7gtsEQ4fjqlWQ93aJYMnO0J5hDXVcyq+/yp+aOvNZvBTbmgyJw92ybMTvvb25wGY2W6/w/R560lK27MixxUdLm6mQrWik8Sbryk6iPslwSs9kP1Z2DxeiP6U57SoECgYEA9Eca78EwUmJRVuEsmLLTXap3bsvFwsz7TcZwUxodKwDWbYu0Csg+H+crsxnDOjljTY7MDfT6T+BniHTlgt1tWgTyvDroGs+VPNsEr9k5XRaf0hqaD3y0IeEw9wJioaB7Mes/5fjejnwZ4lyD2M0GsSRVxSGXqnzh4fP4xCQ9K7ECgYEA7D/NRbXAxJ2S8J1l0IMmWrE3aecV/00vq51YAXjss/YH/Lv/6WmibgOvAROjmdT6Zpptncd8N6heh7S3X3axQ/RM3uxDFOportIlpAdLN6YM7UOdjKbpGt1iQlPzJJ2ziRIp8JP284N/XlAACtQjg5yYuS067iqwnHx5IuKU/isCgYEAuYUrKv1Q4rCyz8XR5eKiblehvy7ZcfnVvhrAggyqLFfFgosAYNP1gqtB4BLn11dwWJ3j0ZHFbVajqtoE2N+sRhrN8zDVyE7xK7e3Fopma5FcLehwKuTttXFei6pvGAtWpPHipJjfBd2wlt7mb4g+1dgfn8jEdAHGV6G/w881+fECgYEA5LJ2si7Z5vtrDUYxE4KCFHVNYVV0c+pyZT0xvmsjKKrY3I3ZlEjQFpO2S+KJExebNsvzpTNBSlfQ+qm0gdNSkqfh6kLoRU0N/X4tNfZhmANErEIyN8A0E++PeQnva9jFvcE5nEyAWQdIuzHSeKkXoAZtyYTBcWEeCr5sPZr+BHUCgYEAiZ2S2J9a71RR5SjbrpzzWFCwg4WksJzBe8oS7xLuA/zPwv2ITBBVZcYhjpHkrO/ZwE+9cP1dorbLus6r/a2vxs4tIbtaLIFoKDHNsIue9XQJObtVE9CbNSqxksp/F4f8Cm4srrdxdGzYz45jxHvOonNC41HYh4wubqycCwXH+Gs=" ],
+ "keyUse" : [ "ENC" ],
+ "certificate" : [ "MIICmzCCAYMCBgGSDEPFSDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQwOTE5MjE0ODQxWhcNMzQwOTE5MjE1MDIxWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhbm40HEOOJjEGVT+L61JSX6YMO0bPBigzUdsS7ZLKfN2+xSnyM128CJI7DncMzPax+OjQVijqnaeUJVTBwybgKx5REGy+R2p/lqdeTGQ9ZD+9R+tvnfDrxdn/ISW/vszE7PMfqS/VRKDtaA7XktQugrfZQ2T6mk1ip9eUf2/xoJjIWcjxDfkbW1Hk8+opyAjpm6+v5YroOMBN7QJ76OqknXJXu4MitHVboKEgB1o6tTuH6tXIvFGDhVzfY35fxRPURAiPaezlPHLtwIuZbetPV0dvNq3gsqXpa5c0yb9a2SzBpLNYyuqw7Aqv9zDFGPolm3IsQXTB6L2yz1hL8/S7AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAALM8s3LBqBOqVTeDNJNkUJ2OhJk1iTr37F1qNJy+gFIokNzE7FaD7obMBD3hoHnW4pOJEIjfLw2N79lH66lY99M2zxC4jhe/d9yqKxoAhzk5MZyPOUnBR1NqQ/n7qfIE/vfPeNdLhyKV0+6V6fBcimXM0El+PCKag8T4HkiLpLs6MuRVOLlaPwKsXCwr24TWnyhcuTvNFmnIVYtryGyCHvJDApAcvak8HlhKiIiDI1PiEaLgoWbhFHpQQLsSfZ+AH7MTSmlY02BbUSnTtqQLLgKRbL2FWKOztHBRK6+dT1xxmIXiNMncUtvcTx8S4088URHf7CGwsg2goOgFomSGwM=" ],
+ "priority" : [ "100" ],
+ "algorithm" : [ "RSA-OAEP" ]
+ }
+ } ]
+ },
+ "internationalizationEnabled" : false,
+ "supportedLocales" : [ ],
+ "authenticationFlows" : [ {
+ "id" : "12923561-6b4d-458a-af19-597a0df4222b",
+ "alias" : "Account verification options",
+ "description" : "Method with which to verity the existing account",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "idp-email-verification",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Verify Existing Account by Re-authentication",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "0741abdd-9046-45e4-9237-2735956a8f67",
+ "alias" : "Browser - Conditional OTP",
+ "description" : "Flow to determine if the OTP is required for the authentication",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "conditional-user-configured",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "auth-otp-form",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "3569f4b2-ebf3-430a-92bd-e3afd3581b39",
+ "alias" : "Direct Grant - Conditional OTP",
+ "description" : "Flow to determine if the OTP is required for the authentication",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "conditional-user-configured",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "direct-grant-validate-otp",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "b063c6d2-033b-409a-a795-78b75451fb5d",
+ "alias" : "First broker login - Conditional OTP",
+ "description" : "Flow to determine if the OTP is required for the authentication",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "conditional-user-configured",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "auth-otp-form",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "ebf694df-ccde-40eb-a048-704583262742",
+ "alias" : "Handle Existing Account",
+ "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "idp-confirm-link",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Account verification options",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "2e74c11b-f429-45cc-a5a2-051d23349da1",
+ "alias" : "Reset - Conditional OTP",
+ "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "conditional-user-configured",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "reset-otp",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "43ca4f2c-b12c-4ab7-b32e-e7ec918f1086",
+ "alias" : "User creation or linking",
+ "description" : "Flow for the existing/non-existing user alternatives",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticatorConfig" : "create unique user config",
+ "authenticator" : "idp-create-user-if-unique",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Handle Existing Account",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "bd7aec0f-5e1b-44fb-8214-49e01adb2a92",
+ "alias" : "Verify Existing Account by Re-authentication",
+ "description" : "Reauthentication of existing account",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "idp-username-password-form",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "CONDITIONAL",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "First broker login - Conditional OTP",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "69e1401f-6146-4217-9c78-60de39b77e5b",
+ "alias" : "browser",
+ "description" : "browser based authentication",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "auth-cookie",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "auth-spnego",
+ "authenticatorFlow" : false,
+ "requirement" : "DISABLED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "identity-provider-redirector",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 25,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 30,
+ "autheticatorFlow" : true,
+ "flowAlias" : "forms",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "de753ad3-bf0a-4cb5-8e63-7f1c61cc4ae6",
+ "alias" : "clients",
+ "description" : "Base authentication for clients",
+ "providerId" : "client-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "client-secret",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "client-jwt",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "client-secret-jwt",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 30,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "client-x509",
+ "authenticatorFlow" : false,
+ "requirement" : "ALTERNATIVE",
+ "priority" : 40,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "c266eeec-c725-4c2c-9274-255066b87888",
+ "alias" : "direct grant",
+ "description" : "OpenID Connect Resource Owner Grant",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "direct-grant-validate-username",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "direct-grant-validate-password",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "CONDITIONAL",
+ "priority" : 30,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Direct Grant - Conditional OTP",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "768f995d-942a-491d-9ddd-e30c94ba7f3f",
+ "alias" : "docker auth",
+ "description" : "Used by Docker clients to authenticate against the IDP",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "docker-http-basic-authenticator",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "2ad6e90c-e6dc-4bdd-b8e6-2bfaa79f5f7e",
+ "alias" : "first broker login",
+ "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticatorConfig" : "review profile config",
+ "authenticator" : "idp-review-profile",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "User creation or linking",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "cde7fa9d-d2fe-4a24-a063-21657ff68666",
+ "alias" : "forms",
+ "description" : "Username, password, otp and other auth forms.",
+ "providerId" : "basic-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "auth-username-password-form",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "CONDITIONAL",
+ "priority" : 20,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Browser - Conditional OTP",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "3382651b-cd94-4f59-ac6b-c86c5f37916e",
+ "alias" : "registration",
+ "description" : "registration flow",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "registration-page-form",
+ "authenticatorFlow" : true,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : true,
+ "flowAlias" : "registration form",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "0b1ddf44-0571-4077-be09-c5034a11bcb0",
+ "alias" : "registration form",
+ "description" : "registration form",
+ "providerId" : "form-flow",
+ "topLevel" : false,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "registration-user-creation",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "registration-password-action",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 50,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "registration-recaptcha-action",
+ "authenticatorFlow" : false,
+ "requirement" : "DISABLED",
+ "priority" : 60,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "registration-terms-and-conditions",
+ "authenticatorFlow" : false,
+ "requirement" : "DISABLED",
+ "priority" : 70,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "0cb25b58-a1c5-4435-8e4c-3dc5b76bf7e5",
+ "alias" : "reset credentials",
+ "description" : "Reset credentials for a user if they forgot their password or something",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "reset-credentials-choose-user",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "reset-credential-email",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 20,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticator" : "reset-password",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 30,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ }, {
+ "authenticatorFlow" : true,
+ "requirement" : "CONDITIONAL",
+ "priority" : 40,
+ "autheticatorFlow" : true,
+ "flowAlias" : "Reset - Conditional OTP",
+ "userSetupAllowed" : false
+ } ]
+ }, {
+ "id" : "5f308482-fe5e-4d4e-82ae-e65bbd2775f6",
+ "alias" : "saml ecp",
+ "description" : "SAML ECP Profile Authentication Flow",
+ "providerId" : "basic-flow",
+ "topLevel" : true,
+ "builtIn" : true,
+ "authenticationExecutions" : [ {
+ "authenticator" : "http-basic-authenticator",
+ "authenticatorFlow" : false,
+ "requirement" : "REQUIRED",
+ "priority" : 10,
+ "autheticatorFlow" : false,
+ "userSetupAllowed" : false
+ } ]
+ } ],
+ "authenticatorConfig" : [ {
+ "id" : "14781383-38bd-4cca-9717-f9a2c0ce74a6",
+ "alias" : "create unique user config",
+ "config" : {
+ "require.password.update.after.registration" : "false"
+ }
+ }, {
+ "id" : "33b3a707-b5e4-4e06-9b20-837e4620da29",
+ "alias" : "review profile config",
+ "config" : {
+ "update.profile.on.first.login" : "missing"
+ }
+ } ],
+ "requiredActions" : [ {
+ "alias" : "CONFIGURE_TOTP",
+ "name" : "Configure OTP",
+ "providerId" : "CONFIGURE_TOTP",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 10,
+ "config" : { }
+ }, {
+ "alias" : "TERMS_AND_CONDITIONS",
+ "name" : "Terms and Conditions",
+ "providerId" : "TERMS_AND_CONDITIONS",
+ "enabled" : false,
+ "defaultAction" : false,
+ "priority" : 20,
+ "config" : { }
+ }, {
+ "alias" : "UPDATE_PASSWORD",
+ "name" : "Update Password",
+ "providerId" : "UPDATE_PASSWORD",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 30,
+ "config" : { }
+ }, {
+ "alias" : "UPDATE_PROFILE",
+ "name" : "Update Profile",
+ "providerId" : "UPDATE_PROFILE",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 40,
+ "config" : { }
+ }, {
+ "alias" : "VERIFY_EMAIL",
+ "name" : "Verify Email",
+ "providerId" : "VERIFY_EMAIL",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 50,
+ "config" : { }
+ }, {
+ "alias" : "delete_account",
+ "name" : "Delete Account",
+ "providerId" : "delete_account",
+ "enabled" : false,
+ "defaultAction" : false,
+ "priority" : 60,
+ "config" : { }
+ }, {
+ "alias" : "webauthn-register",
+ "name" : "Webauthn Register",
+ "providerId" : "webauthn-register",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 70,
+ "config" : { }
+ }, {
+ "alias" : "webauthn-register-passwordless",
+ "name" : "Webauthn Register Passwordless",
+ "providerId" : "webauthn-register-passwordless",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 80,
+ "config" : { }
+ }, {
+ "alias" : "VERIFY_PROFILE",
+ "name" : "Verify Profile",
+ "providerId" : "VERIFY_PROFILE",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 90,
+ "config" : { }
+ }, {
+ "alias" : "delete_credential",
+ "name" : "Delete Credential",
+ "providerId" : "delete_credential",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 100,
+ "config" : { }
+ }, {
+ "alias" : "update_user_locale",
+ "name" : "Update User Locale",
+ "providerId" : "update_user_locale",
+ "enabled" : true,
+ "defaultAction" : false,
+ "priority" : 1000,
+ "config" : { }
+ } ],
+ "browserFlow" : "browser",
+ "registrationFlow" : "registration",
+ "directGrantFlow" : "direct grant",
+ "resetCredentialsFlow" : "reset credentials",
+ "clientAuthenticationFlow" : "clients",
+ "dockerAuthenticationFlow" : "docker auth",
+ "firstBrokerLoginFlow" : "first broker login",
+ "attributes" : {
+ "cibaBackchannelTokenDeliveryMode" : "poll",
+ "cibaExpiresIn" : "120",
+ "cibaAuthRequestedUserHint" : "login_hint",
+ "parRequestUriLifespan" : "60",
+ "cibaInterval" : "5",
+ "realmReusableOtpCode" : "false"
+ },
+ "keycloakVersion" : "25.0.5",
+ "userManagedAccessAllowed" : false,
+ "organizationsEnabled" : false,
+ "clientProfiles" : {
+ "profiles" : [ ]
+ },
+ "clientPolicies" : {
+ "policies" : [ ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml
index 269d26fe9..4fd4c9198 100644
--- a/src/test/resources/logback-test.xml
+++ b/src/test/resources/logback-test.xml
@@ -1,10 +1,10 @@
+
-
@@ -14,13 +14,16 @@
-
+
+ {"app":"keycloak-config-cli"}
+
-
-
-
+
+
+
+