From 52e17bcefadca0d8793b1895d41c2ffca1f51956 Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Thu, 13 Jul 2023 19:38:23 +0200 Subject: [PATCH] Add Keycloak 22, remove Keycloak 18 - Rewrite jakarta packages to javax packages before ci build for older Keycloak versions with maven-replacer-plugin - Use older resteasy version (4.7.7.Final) for Keycloak < 22.0.0 in ci - Add workaround to ResteasyUtil for missing isClose() method in older Resteasy JAX-RS Response type - Required jakarta dependencies - Make cookie handling in CookieClientFilter more robust - add generated master realm for 22.0.0 - Add missing mockServerClient request responder - Extend checkstyle config: Moved jakarta imports to SPECIAL import group that follows STANDARD_JAVA_PACKAGE import group - Adjusted realm setting internationalizationEnabled in test config files with is now required for managing user locale via attributes We need to configure internationalizationEnabled to be able to supply a locale attribute during user creation The enforcement was introduced in Keycloak 22.0.0, see: keycloak/keycloak@d0691b0 but the realm property exists for many years already and is thus safe to set. Fixes #897 --- .env | 2 +- .github/workflows/ci.yaml | 28 +- CHANGELOG.md | 5 + Dockerfile | 2 +- README.md | 2 +- checkstyle.xml | 4 +- pom.xml | 105 +- .../config/provider/KeycloakProvider.java | 9 +- .../AuthenticationFlowRepository.java | 9 +- .../config/repository/ClientRepository.java | 5 +- .../repository/ClientScopeRepository.java | 5 +- .../repository/ComponentRepository.java | 5 +- .../repository/ExecutionFlowRepository.java | 5 +- .../config/repository/GroupRepository.java | 3 +- .../IdentityProviderMapperRepository.java | 3 +- .../IdentityProviderRepository.java | 5 +- .../config/repository/RealmRepository.java | 5 +- .../repository/RequiredActionRepository.java | 4 +- .../config/repository/RoleRepository.java | 8 +- .../repository/UserProfileRepository.java | 3 +- .../config/repository/UserRepository.java | 3 +- .../resource/ManagementPermissions.java | 7 +- .../ClientAuthorizationImportService.java | 3 +- .../config/service/ClientImportService.java | 3 +- .../service/DefaultGroupsImportService.java | 4 +- .../service/ExecutionFlowsImportService.java | 3 +- .../ClientPermissionResolver.java | 2 +- .../GroupPermissionResolver.java | 2 +- .../RolePermissionResolver.java | 2 +- .../keycloak/config/util/ResponseUtil.java | 11 +- .../keycloak/config/util/ResteasyUtil.java | 2 +- .../util/resteasy/CookieClientFilter.java | 14 +- .../keycloak/config/mock/CookieMockIT.java | 1 + .../config/provider/KeycloakProviderIT.java | 4 +- .../config/service/ImportUsersIT.java | 5 +- .../exported-realm/22.0.0/master-realm.json | 1745 +++++++++++++++++ ...1_import_realm_with_nested_composites.json | 1 + ...2_import_realm_with_nested_composites.json | 1 + ...3_import_realm_with_nested_composites.json | 1 + .../users/00_create_realm_with_user.json | 1 + .../users/01_update_realm_add_clientuser.json | 1 + ...ate_realm_change_clientusers_password.json | 1 + ...ate_realm_change_clientusers_password.json | 1 + ...th_email_as_username_without_username.json | 1 + ...th_email_as_username_without_username.json | 1 + ...ail_as_username_with_invalid_username.json | 1 + ...ail_as_username_with_correct_username.json | 1 + 47 files changed, 1975 insertions(+), 64 deletions(-) create mode 100644 src/test/resources/import-files/exported-realm/22.0.0/master-realm.json diff --git a/.env b/.env index 0839976e7..087047da5 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ # Used in docker-compose # shellcheck disable=SC2034 -KEYCLOAK_VERSION=21.1.1 +KEYCLOAK_VERSION=22.0.0 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b3e0706d9..d4406bf57 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -27,10 +27,10 @@ jobs: fail-fast: false matrix: env: - - KEYCLOAK_VERSION: 18.0.2 - KEYCLOAK_VERSION: 19.0.3 - KEYCLOAK_VERSION: 20.0.5 - KEYCLOAK_VERSION: 21.1.1 + - KEYCLOAK_VERSION: 22.0.0 steps: - uses: actions/checkout@v3 with: @@ -48,8 +48,14 @@ jobs: key: ${{ runner.os }}-maven-${{ matrix.env.KEYCLOAK_VERSION }}-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-maven-${{ matrix.env.KEYCLOAK_VERSION }} + - name: Adapt sources for Keycloak versions < 22.0.0 (jakarta -> javax) + if: ${{ matrix.env.KEYCLOAK_VERSION < '22.0.0' }} + run: | + echo "JAVAX_PROFILE=-Pjavax" >> $GITHUB_ENV + echo "ADJUSTED_RESTEASY_VERSION=-Dresteasy.version=4.7.7.Final" >> $GITHUB_ENV + - name: Build & Test - run: ./mvnw ${MAVEN_CLI_OPTS} -Dkeycloak.version=${{ matrix.env.KEYCLOAK_VERSION }} clean verify -Pcoverage + run: ./mvnw ${MAVEN_CLI_OPTS} -Dkeycloak.version=${{ matrix.env.KEYCLOAK_VERSION }} ${ADJUSTED_RESTEASY_VERSION} clean verify -Pcoverage ${JAVAX_PROFILE} - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 @@ -106,7 +112,7 @@ jobs: with: build-args: |- KEYCLOAK_VERSION=${{ matrix.env.KEYCLOAK_VERSION }} - MAVEN_CLI_OPTS=${{ env.MAVEN_CLI_OPTS }} + MAVEN_CLI_OPTS=${{ env.MAVEN_CLI_OPTS }} ${{ env.ADJUSTED_RESTEASY_VERSION }} ${{ env.JAVAX_PROFILE }} cache-from: type=gha cache-to: type=gha,mode=max context: . @@ -151,8 +157,14 @@ jobs: key: ${{ runner.os }}-${{ matrix.java }}-maven-build-pom-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-${{ matrix.java }}-maven-build-pom + - name: Adapt sources for Keycloak versions < 22.0.0 (jakarta -> javax) + if: ${{ matrix.env.KEYCLOAK_VERSION < '22.0.0' }} + run: | + echo "JAVAX_PROFILE=-Pjavax" >> $GITHUB_ENV + echo "ADJUSTED_RESTEASY_VERSION=-Dresteasy.version=4.7.7.Final" >> $GITHUB_ENV + - name: Build & Test - run: ./mvnw ${MAVEN_CLI_OPTS} clean verify + run: ./mvnw ${MAVEN_CLI_OPTS} ${ADJUSTED_RESTEASY_VERSION} clean verify ${JAVAX_PROFILE} build-legacy: runs-on: ubuntu-latest @@ -178,8 +190,14 @@ jobs: restore-keys: | ${{ runner.os }}-maven-keycloak-legacy + - name: Adapt sources for Keycloak versions < 22.0.0 (jakarta -> javax) + if: ${{ matrix.env.KEYCLOAK_VERSION < '22.0.0' }} + run: | + echo "JAVAX_PROFILE=-Pjavax" >> $GITHUB_ENV + echo "ADJUSTED_RESTEASY_VERSION=-Dresteasy.version=4.7.7.Final" >> $GITHUB_ENV + - name: Build & Test - run: ./mvnw ${MAVEN_CLI_OPTS} -Dkeycloak.version=${{ matrix.env.KEYCLOAK_VERSION }} -Dkeycloak.dockerTagSuffix="" clean verify + run: ./mvnw ${MAVEN_CLI_OPTS} -Dkeycloak.version=${{ matrix.env.KEYCLOAK_VERSION }} -Dkeycloak.dockerTagSuffix="" ${ADJUSTED_RESTEASY_VERSION} clean verify ${JAVAX_PROFILE} lint-other-files: runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d97a2370..f6ab0bfc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - in the end, the `userProfile` property should match the content of the "JSON editor" tab in the "Realm settings > User profile" page from the Keycloak admin console - Add support for managing client-policies +## [5.7.0] +- Added support for Keycloak 22 +- Update to Spring Boot 2.7.13 +- Adapt packages for Jakarta EE migration + ## [5.6.1] - 2023-03-05 ## [5.6.0] - 2023-03-05 diff --git a/Dockerfile b/Dockerfile index b8491f608..314460c07 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ FROM ${BUILDER_IMAGE} AS BUILDER WORKDIR /app/ -ARG KEYCLOAK_VERSION=21.1.1 +ARG KEYCLOAK_VERSION=22.0.0 ARG MAVEN_CLI_OPTS="-ntp -B" COPY .mvn .mvn diff --git a/README.md b/README.md index 72ab829ae..3f993ece0 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ Additionally, the tag `maven` contains the source code and compile keycloak-conf Keycloak versions, that not official supported., e.g.: ```bash -docker run --rm -ti -v $PWD:/config/ -eKEYCLOAK_VERSION=17.0.0 -eMAVEN_CLI_OPTS="-B -ntp -q" adorsys/keycloak-config-cli:edge-build +docker run --rm -ti -v $PWD:/config/ -eKEYCLOAK_VERSION=22.0.0 -eMAVEN_CLI_OPTS="-B -ntp -q" adorsys/keycloak-config-cli:edge-build ``` ### Docker run diff --git a/checkstyle.xml b/checkstyle.xml index 14e0381e1..37a2d5420 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -277,8 +277,10 @@ + + - + diff --git a/pom.xml b/pom.xml index 7a2a55e08..162b047e1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.springframework.boot spring-boot-starter-parent - 2.7.12 + 2.7.13 @@ -59,7 +59,7 @@ UTF-8 UTF-8 - 21.1.1 + 22.0.0 3.2.0 10.0 @@ -84,7 +84,13 @@ 3.21.0 6.55.0 0.15 - 5.0.4.Final + 6.2.4.Final + 2.0 + 3.1.0 + 2.1.2 + 2.1.1 + 2.1.2 + 5.8.4 4.7.3.5 4.7.3 1.18.3 @@ -161,6 +167,12 @@ org.springframework.boot spring-boot-starter + + + jakarta.annotation + jakarta.annotation-api + + @@ -177,7 +189,7 @@ org.springframework.security spring-security-crypto - 5.8.3 + ${spring-security-crypto.version} @@ -194,7 +206,7 @@ org.yaml snakeyaml - 2.0 + ${snakeyaml.version} @@ -205,6 +217,53 @@ org.jboss.resteasy resteasy-jaxb-provider + + + jakarta.activation + jakarta.activation-api + + + jakarta.annotation + jakarta.annotation-api + + + jakarta.mail + jakarta.mail-api + + + jakarta.ws.rs + jakarta.ws.rs-api + + + + + + jakarta.ws.rs + jakarta.ws.rs-api + ${jakarta.ws.rs-api.version} + + + + jakarta.activation + jakarta.activation-api + ${jakarta.activation.version} + + + + jakarta.annotation + jakarta.annotation-api + ${jakarta.annotation.version} + + + + jakarta.mail + jakarta.mail-api + ${jakarta.mail.version} + + + jakarta.activation + jakarta.activation-api + @@ -571,7 +630,6 @@ checkstyle.xml false - ${project.reporting.outputEncoding} true true false @@ -633,6 +691,41 @@ + + javax + + + + com.google.code.maven-replacer-plugin + replacer + ${maven-replacer.version} + + + replace-import-javax-by-jakarta + generate-sources + + replace + + + + + + ${project.basedir}/src + + + **/*.java + + + + import jakarta + import javax + + + + + + + coverage 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 13782648f..06474c3b4 100644 --- a/src/main/java/de/adorsys/keycloak/config/provider/KeycloakProvider.java +++ b/src/main/java/de/adorsys/keycloak/config/provider/KeycloakProvider.java @@ -40,10 +40,11 @@ import java.net.URL; import java.text.MessageFormat; import java.time.Duration; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.Form; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.core.Form; +import jakarta.ws.rs.core.Response; /** * This class exists because we need to create a single keycloak instance or to close the keycloak before using a new one 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 01eb48509..959f68d12 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/AuthenticationFlowRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/AuthenticationFlowRepository.java @@ -38,10 +38,11 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import javax.ws.rs.ClientErrorException; -import javax.ws.rs.NotFoundException; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.ClientErrorException; +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; @Service public class AuthenticationFlowRepository { 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 2116a393f..aed7d7649 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/ClientRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/ClientRepository.java @@ -42,8 +42,9 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; @Service public class ClientRepository { 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 e70a46100..e6d9093f4 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/ClientScopeRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/ClientScopeRepository.java @@ -36,8 +36,9 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; @Service public class ClientScopeRepository { 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 25957dbe6..388f05073 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/ComponentRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/ComponentRepository.java @@ -34,8 +34,9 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; @Service public class ComponentRepository { 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 ad429c4e7..e176152ca 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/ExecutionFlowRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/ExecutionFlowRepository.java @@ -37,8 +37,9 @@ import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.Response; @Service public class ExecutionFlowRepository { 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 88628176f..7ce265ee1 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/GroupRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/GroupRepository.java @@ -39,7 +39,8 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.core.Response; @Service public class GroupRepository { 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 ac71c2b65..dc03e245e 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderMapperRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderMapperRepository.java @@ -32,7 +32,8 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.core.Response; @Service public class IdentityProviderMapperRepository { 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 aa7301c3e..14c89315c 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/IdentityProviderRepository.java @@ -32,8 +32,9 @@ import java.util.List; import java.util.Optional; -import javax.ws.rs.NotFoundException; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.core.Response; @Service public class IdentityProviderRepository { 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 c71a6483a..8a6d44c48 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/RealmRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/RealmRepository.java @@ -30,7 +30,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import javax.ws.rs.WebApplicationException; +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.WebApplicationException; @Service public class RealmRepository { @@ -44,7 +45,7 @@ public RealmRepository(KeycloakProvider keycloakProvider) { public boolean exists(String realmName) { try { get(realmName); - } catch (javax.ws.rs.NotFoundException e) { + } catch (NotFoundException e) { return false; } 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 4b55fb683..b6d91be12 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/RequiredActionRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/RequiredActionRepository.java @@ -30,6 +30,8 @@ import java.util.List; import java.util.Objects; +import jakarta.ws.rs.NotFoundException; + /** * Provides methods to retrieve and store required-actions in your realm */ @@ -63,7 +65,7 @@ public RequiredActionProviderRepresentation getByAlias(String realmName, String try { AuthenticationManagementResource flows = authenticationFlowRepository.getFlowResources(realmName); return flows.getRequiredAction(requiredActionAlias); - } catch (javax.ws.rs.NotFoundException e) { + } catch (NotFoundException e) { return null; } } 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 94833431c..c7472e714 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/RoleRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/RoleRepository.java @@ -33,6 +33,8 @@ import java.util.*; import java.util.stream.Collectors; +import jakarta.ws.rs.NotFoundException; + @Service public class RoleRepository { private final RealmRepository realmRepository; @@ -60,7 +62,7 @@ public Optional searchRealmRole(String realmName, String nam try { maybeRole = Optional.of(roleResource.toRepresentation()); - } catch (javax.ws.rs.NotFoundException e) { + } catch (NotFoundException e) { maybeRole = Optional.empty(); } @@ -136,7 +138,7 @@ public List getClientRolesByName(String realmName, String cl for (String roleName : roleNames) { try { roles.add(clientResource.roles().get(roleName).toRepresentation()); - } catch (javax.ws.rs.NotFoundException e) { + } catch (NotFoundException e) { throw new KeycloakRepositoryException( "Cannot find client role '%s' for client '%s' within realm '%s'", roleName, clientId, realmName @@ -179,7 +181,7 @@ public List searchRealmRoles(String realmName, List RoleRepresentation role = realmResource.roles().get(roleName).toRepresentation(); roles.add(role); - } catch (javax.ws.rs.NotFoundException e) { + } catch (NotFoundException e) { throw new ImportProcessingException( String.format("Could not find role '%s' in realm '%s'!", roleName, realmName) ); 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 b15113b69..1e16a64ce 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java @@ -30,7 +30,8 @@ import org.springframework.util.StringUtils; import java.util.Optional; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.core.Response; @Component public class UserProfileRepository { 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 e778751a2..e6ba35d2a 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/UserRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/UserRepository.java @@ -32,7 +32,8 @@ import java.util.List; import java.util.Optional; -import javax.ws.rs.core.Response; + +import jakarta.ws.rs.core.Response; @Service public class UserRepository { diff --git a/src/main/java/de/adorsys/keycloak/config/resource/ManagementPermissions.java b/src/main/java/de/adorsys/keycloak/config/resource/ManagementPermissions.java index bb46b28fc..91c977200 100644 --- a/src/main/java/de/adorsys/keycloak/config/resource/ManagementPermissions.java +++ b/src/main/java/de/adorsys/keycloak/config/resource/ManagementPermissions.java @@ -23,7 +23,12 @@ import org.keycloak.representations.idm.ManagementPermissionReference; import org.keycloak.representations.idm.ManagementPermissionRepresentation; -import javax.ws.rs.*; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; /** * Routes which are somehow missing from the official Keycloak client library 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 1663b2b7d..4d93b127e 100644 --- a/src/main/java/de/adorsys/keycloak/config/service/ClientAuthorizationImportService.java +++ b/src/main/java/de/adorsys/keycloak/config/service/ClientAuthorizationImportService.java @@ -47,7 +47,8 @@ import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; -import javax.ws.rs.NotFoundException; + +import jakarta.ws.rs.NotFoundException; import static de.adorsys.keycloak.config.properties.ImportConfigProperties.ImportManagedProperties.ImportManagedPropertiesValues.FULL; import static java.lang.Boolean.TRUE; 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 ea0c64b53..e9c006e76 100644 --- a/src/main/java/de/adorsys/keycloak/config/service/ClientImportService.java +++ b/src/main/java/de/adorsys/keycloak/config/service/ClientImportService.java @@ -40,7 +40,8 @@ import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; -import javax.ws.rs.WebApplicationException; + +import jakarta.ws.rs.WebApplicationException; import static de.adorsys.keycloak.config.properties.ImportConfigProperties.ImportManagedProperties.ImportManagedPropertiesValues.FULL; import static java.lang.Boolean.TRUE; 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 8f7f0823b..e10f91849 100644 --- a/src/main/java/de/adorsys/keycloak/config/service/DefaultGroupsImportService.java +++ b/src/main/java/de/adorsys/keycloak/config/service/DefaultGroupsImportService.java @@ -30,6 +30,8 @@ import java.util.List; +import jakarta.ws.rs.NotFoundException; + @Service public class DefaultGroupsImportService { private final RealmRepository realmRepository; @@ -67,7 +69,7 @@ public void doImport(RealmImport realmImport) { try { String newDefaultGroupId = groupRepository.getGroupByPath(realmName, newDefaultGroup).getId(); realmResource.addDefaultGroup(newDefaultGroupId); - } catch (javax.ws.rs.NotFoundException ignored) { + } catch (NotFoundException ignored) { throw new InvalidImportException(String.format("Unable to add default group '%s'. Does group exists?", newDefaultGroup)); } } 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 ae885891f..482d605db 100644 --- a/src/main/java/de/adorsys/keycloak/config/service/ExecutionFlowsImportService.java +++ b/src/main/java/de/adorsys/keycloak/config/service/ExecutionFlowsImportService.java @@ -38,7 +38,8 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -import javax.ws.rs.WebApplicationException; + +import jakarta.ws.rs.WebApplicationException; /** * Imports executions and execution-flows of existing top-level flows diff --git a/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/ClientPermissionResolver.java b/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/ClientPermissionResolver.java index dbb9f2097..c1fb910ec 100644 --- a/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/ClientPermissionResolver.java +++ b/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/ClientPermissionResolver.java @@ -26,7 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.ws.rs.NotFoundException; +import jakarta.ws.rs.NotFoundException; public class ClientPermissionResolver implements PermissionResolver { private static final Logger logger = LoggerFactory.getLogger(ClientPermissionResolver.class); diff --git a/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/GroupPermissionResolver.java b/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/GroupPermissionResolver.java index 59a0e7231..6580e16b0 100644 --- a/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/GroupPermissionResolver.java +++ b/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/GroupPermissionResolver.java @@ -26,7 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.ws.rs.NotFoundException; +import jakarta.ws.rs.NotFoundException; public class GroupPermissionResolver implements PermissionResolver { private static final Logger logger = LoggerFactory.getLogger(GroupPermissionResolver.class); diff --git a/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/RolePermissionResolver.java b/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/RolePermissionResolver.java index ec7bef3d5..46e813160 100644 --- a/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/RolePermissionResolver.java +++ b/src/main/java/de/adorsys/keycloak/config/service/clientauthorization/RolePermissionResolver.java @@ -26,7 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.ws.rs.NotFoundException; +import jakarta.ws.rs.NotFoundException; public class RolePermissionResolver implements PermissionResolver { private static final Logger logger = LoggerFactory.getLogger(RolePermissionResolver.class); diff --git a/src/main/java/de/adorsys/keycloak/config/util/ResponseUtil.java b/src/main/java/de/adorsys/keycloak/config/util/ResponseUtil.java index df34bda18..328088368 100644 --- a/src/main/java/de/adorsys/keycloak/config/util/ResponseUtil.java +++ b/src/main/java/de/adorsys/keycloak/config/util/ResponseUtil.java @@ -20,9 +20,7 @@ package de.adorsys.keycloak.config.util; -import org.jboss.resteasy.client.jaxrs.internal.ClientResponse; - -import javax.ws.rs.WebApplicationException; +import jakarta.ws.rs.WebApplicationException; public class ResponseUtil { ResponseUtil() { @@ -30,7 +28,12 @@ public class ResponseUtil { } public static String getErrorMessage(WebApplicationException error) { - String errorBody = !((ClientResponse) error.getResponse()).isClosed() ? error.getResponse().readEntity(String.class).trim() : ""; + String errorBody; + try { + errorBody = error.getResponse().readEntity(String.class).trim(); + } catch (Exception ignore) { + errorBody = ""; + } return error.getMessage() + errorBody; } } diff --git a/src/main/java/de/adorsys/keycloak/config/util/ResteasyUtil.java b/src/main/java/de/adorsys/keycloak/config/util/ResteasyUtil.java index 79b584628..93e64a91a 100644 --- a/src/main/java/de/adorsys/keycloak/config/util/ResteasyUtil.java +++ b/src/main/java/de/adorsys/keycloak/config/util/ResteasyUtil.java @@ -61,7 +61,7 @@ public static ResteasyClient getClient(boolean sslVerification, URL httpProxy, D ); } - clientBuilder.register(new CookieClientFilter()); + clientBuilder.register(CookieClientFilter.class); return clientBuilder.build(); } diff --git a/src/main/java/de/adorsys/keycloak/config/util/resteasy/CookieClientFilter.java b/src/main/java/de/adorsys/keycloak/config/util/resteasy/CookieClientFilter.java index d8a3109ad..2ef15e4ee 100644 --- a/src/main/java/de/adorsys/keycloak/config/util/resteasy/CookieClientFilter.java +++ b/src/main/java/de/adorsys/keycloak/config/util/resteasy/CookieClientFilter.java @@ -23,17 +23,23 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import javax.ws.rs.client.ClientRequestContext; -import javax.ws.rs.client.ClientRequestFilter; -import javax.ws.rs.client.ClientResponseContext; -import javax.ws.rs.client.ClientResponseFilter; + +import jakarta.ws.rs.client.ClientRequestContext; +import jakarta.ws.rs.client.ClientRequestFilter; +import jakarta.ws.rs.client.ClientResponseContext; +import jakarta.ws.rs.client.ClientResponseFilter; // By default, the RESTeasy cookie handling is very limited. There is no access to the underlying httpEngine. // The underlying httpEngine uses an old CookieSpec by default which is going to refuse valid cookie today. // Instead, build the httpEngine from scratch, we are using a RESTeasy filter to grab a re-attach cookie. // Currently, this filter does not valide cookie or is able to remove cookies. // A cookie managed is required to handle sticky sessions at cookie base + public class CookieClientFilter implements ClientRequestFilter, ClientResponseFilter { + + /** + * Holds the additional cookies across multiple interactions in the same thread. + */ private final ThreadLocal> cookies = ThreadLocal.withInitial(HashMap::new); @Override diff --git a/src/test/java/de/adorsys/keycloak/config/mock/CookieMockIT.java b/src/test/java/de/adorsys/keycloak/config/mock/CookieMockIT.java index 51bd416f9..ecb602521 100644 --- a/src/test/java/de/adorsys/keycloak/config/mock/CookieMockIT.java +++ b/src/test/java/de/adorsys/keycloak/config/mock/CookieMockIT.java @@ -57,6 +57,7 @@ class CookieMockIT extends AbstractImportTest { @Test void run() throws Exception { mockServerClient.when(request().withPath("/realms/master/protocol/openid-connect/token")).respond(KeycloakMock::grantToken); + mockServerClient.when(request().withPath("/admin/realms")).respond(KeycloakMock::realm); mockServerClient.when(request().withPath("/admin/realms/simple")).respond(KeycloakMock::realm); mockServerClient.when(request().withPath("/admin/realms/simple/default-default-client-scopes")).respond(KeycloakMock::emptyList); mockServerClient.when(request().withPath("/admin/realms/simple/default-optional-client-scopes")).respond(KeycloakMock::emptyList); diff --git a/src/test/java/de/adorsys/keycloak/config/provider/KeycloakProviderIT.java b/src/test/java/de/adorsys/keycloak/config/provider/KeycloakProviderIT.java index 35b93c88b..1a5ecef28 100644 --- a/src/test/java/de/adorsys/keycloak/config/provider/KeycloakProviderIT.java +++ b/src/test/java/de/adorsys/keycloak/config/provider/KeycloakProviderIT.java @@ -33,8 +33,8 @@ import java.net.SocketTimeoutException; import java.net.URISyntaxException; -import javax.ws.rs.NotFoundException; -import javax.ws.rs.ProcessingException; +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.ProcessingException; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.matchesPattern; diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportUsersIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportUsersIT.java index 965d7cd2d..e64f79bab 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportUsersIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportUsersIT.java @@ -24,6 +24,7 @@ import de.adorsys.keycloak.config.exception.ImportProcessingException; import de.adorsys.keycloak.config.exception.InvalidImportException; import de.adorsys.keycloak.config.model.RealmImport; +import jakarta.ws.rs.NotAuthorizedException; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.keycloak.admin.client.resource.RealmResource; @@ -146,7 +147,7 @@ void shouldUpdateRealmWithChangedClientUserPassword() throws IOException { assertThat(user.getLastName(), is("My clientuser's lastname")); // check if login with old password fails - assertThrows(javax.ws.rs.NotAuthorizedException.class, () -> + assertThrows(NotAuthorizedException.class, () -> keycloakAuthentication.login( REALM_NAME, "moped-client", @@ -204,7 +205,7 @@ void shouldUpdateRealmWithChangedClientUserPassword() throws IOException { // check if login with new password fails - assertThrows(javax.ws.rs.NotAuthorizedException.class, () -> + assertThrows(NotAuthorizedException.class, () -> keycloakAuthentication.login( REALM_NAME, "moped-client", diff --git a/src/test/resources/import-files/exported-realm/22.0.0/master-realm.json b/src/test/resources/import-files/exported-realm/22.0.0/master-realm.json new file mode 100644 index 000000000..2af2d745a --- /dev/null +++ b/src/test/resources/import-files/exported-realm/22.0.0/master-realm.json @@ -0,0 +1,1745 @@ +{ + "id" : "1ccd1e28-6d77-40d6-bc59-defd3c57ab33", + "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, + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "bd30934c-a5b2-49f6-b1ff-20c24656e072", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "composite" : false, + "clientRole" : false, + "containerId" : "1ccd1e28-6d77-40d6-bc59-defd3c57ab33", + "attributes" : { } + }, { + "id" : "5967030d-91af-44a8-83bf-f9b8135cf057", + "name" : "offline_access", + "description" : "${role_offline-access}", + "composite" : false, + "clientRole" : false, + "containerId" : "1ccd1e28-6d77-40d6-bc59-defd3c57ab33", + "attributes" : { } + }, { + "id" : "b01f8767-4d33-4b6e-989c-a281c4f22399", + "name" : "admin", + "description" : "${role_admin}", + "composite" : true, + "composites" : { + "realm" : [ "create-realm" ], + "client" : { + "master-realm" : [ "query-users", "view-authorization", "view-identity-providers", "manage-authorization", "manage-clients", "create-client", "view-events", "impersonation", "view-clients", "manage-users", "query-clients", "view-users", "query-realms", "manage-realm", "query-groups", "manage-identity-providers", "manage-events", "view-realm" ] + } + }, + "clientRole" : false, + "containerId" : "1ccd1e28-6d77-40d6-bc59-defd3c57ab33", + "attributes" : { } + }, { + "id" : "525807d9-1577-4734-95e2-6564172b3a9b", + "name" : "create-realm", + "description" : "${role_create-realm}", + "composite" : false, + "clientRole" : false, + "containerId" : "1ccd1e28-6d77-40d6-bc59-defd3c57ab33", + "attributes" : { } + }, { + "id" : "ed37abd9-5a3a-41c6-ac2d-ef4e1ef8201d", + "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" : "1ccd1e28-6d77-40d6-bc59-defd3c57ab33", + "attributes" : { } + } ], + "client" : { + "security-admin-console" : [ ], + "admin-cli" : [ ], + "account-console" : [ ], + "broker" : [ { + "id" : "37a208d9-0282-4099-a6f5-63e03b6fb55a", + "name" : "read-token", + "description" : "${role_read-token}", + "composite" : false, + "clientRole" : true, + "containerId" : "b5ee4d95-8ead-4ef6-9939-20884c591b71", + "attributes" : { } + } ], + "master-realm" : [ { + "id" : "6914baad-bfa4-4930-b7c2-8f36939a6e2c", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "116c0571-947e-4dfe-b942-5dd98151b7f5", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "45afb2db-a4a0-4233-bf0b-989f6b0813ee", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "1b4f0c02-c1c6-4f70-841a-5bb011ce04b9", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "501a0d25-e5b8-48b6-bdf6-02b59dabfc11", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "9852e5b4-fefe-4a66-bf80-5b697a907dcc", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "b07b8d7a-89d3-4eef-949f-854b6841a7ff", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "01bb605d-634b-4286-8e6b-ee8f920a117d", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "231660ee-8e17-417d-9294-52b9f9d35026", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "master-realm" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "0daca8a5-6e61-4361-bdbc-87f15a5f51de", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "93ee36f1-0c46-4c12-b21e-269f6f9c778f", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "fb83d2eb-4ddc-46e2-8580-f5d51a80a909", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "master-realm" : [ "query-users", "query-groups" ] + } + }, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "9e9c7109-b1e5-45cc-a9f8-1b3245bb51cf", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "2cfa0b34-6425-4282-becc-2ad63b60f875", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "c5262f2d-b1f7-4f2b-9eed-6ef2e564061e", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "3ca99fa1-880e-495b-ab29-8d476ef9293f", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "34d23022-7ed5-4dab-9c75-bead7dc95e8e", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + }, { + "id" : "de9e055e-8079-4b2e-a509-eaf2b671396d", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "attributes" : { } + } ], + "account" : [ { + "id" : "b050cd9b-b779-4c4c-b7dc-49e06c95d8c6", + "name" : "delete-account", + "description" : "${role_delete-account}", + "composite" : false, + "clientRole" : true, + "containerId" : "0527f8d7-0862-4025-b58d-8e4d18253586", + "attributes" : { } + }, { + "id" : "ee04e4a4-c18d-43c6-8cd6-7eee0bb9814c", + "name" : "view-consent", + "description" : "${role_view-consent}", + "composite" : false, + "clientRole" : true, + "containerId" : "0527f8d7-0862-4025-b58d-8e4d18253586", + "attributes" : { } + }, { + "id" : "d9c43077-4390-45ed-8bed-2eb4876d5923", + "name" : "view-groups", + "description" : "${role_view-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "0527f8d7-0862-4025-b58d-8e4d18253586", + "attributes" : { } + }, { + "id" : "8a73ae6c-3332-40e1-ada4-99050984b92f", + "name" : "view-profile", + "description" : "${role_view-profile}", + "composite" : false, + "clientRole" : true, + "containerId" : "0527f8d7-0862-4025-b58d-8e4d18253586", + "attributes" : { } + }, { + "id" : "8b54b609-7e8b-4259-a015-43c410ed5513", + "name" : "view-applications", + "description" : "${role_view-applications}", + "composite" : false, + "clientRole" : true, + "containerId" : "0527f8d7-0862-4025-b58d-8e4d18253586", + "attributes" : { } + }, { + "id" : "aec80629-4c28-468c-9716-7b1053e9ec16", + "name" : "manage-account", + "description" : "${role_manage-account}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "manage-account-links" ] + } + }, + "clientRole" : true, + "containerId" : "0527f8d7-0862-4025-b58d-8e4d18253586", + "attributes" : { } + }, { + "id" : "86f5e9e0-3779-4bb3-bae7-41e0f16a6f62", + "name" : "manage-account-links", + "description" : "${role_manage-account-links}", + "composite" : false, + "clientRole" : true, + "containerId" : "0527f8d7-0862-4025-b58d-8e4d18253586", + "attributes" : { } + }, { + "id" : "3e0f2eee-3f9b-43cd-93c0-35ea7c75f56e", + "name" : "manage-consent", + "description" : "${role_manage-consent}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "view-consent" ] + } + }, + "clientRole" : true, + "containerId" : "0527f8d7-0862-4025-b58d-8e4d18253586", + "attributes" : { } + } ] + } + }, + "groups" : [ ], + "defaultRole" : { + "id" : "ed37abd9-5a3a-41c6-ac2d-ef4e1ef8201d", + "name" : "default-roles-master", + "description" : "${role_default-roles}", + "composite" : true, + "clientRole" : false, + "containerId" : "1ccd1e28-6d77-40d6-bc59-defd3c57ab33" + }, + "requiredCredentials" : [ "password" ], + "otpPolicyType" : "totp", + "otpPolicyAlgorithm" : "HmacSHA1", + "otpPolicyInitialCounter" : 0, + "otpPolicyDigits" : 6, + "otpPolicyLookAheadWindow" : 1, + "otpPolicyPeriod" : 30, + "otpPolicyCodeReusable" : false, + "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName" ], + "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" : "0527f8d7-0862-4025-b58d-8e4d18253586", + "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", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "834a1459-ba31-4e65-873a-32388946114d", + "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" : "3f504b40-abf3-440d-af78-a40afbbd858e", + "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" : "7cf3b2af-3947-4a4d-8906-c8b4e977d974", + "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" : "b5ee4d95-8ead-4ef6-9939-20884c591b71", + "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" : "66a91519-db9c-4bd7-acb5-2dd0101d3cc8", + "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", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "54b074a8-e7bf-46e0-833c-00e1839f8ebf", + "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" : "4569fd57-33ea-419d-b0c4-7bc88162d72e", + "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" : "e04b5640-f55e-4e90-a4f5-7d4c0d8cb105", + "name" : "role_list", + "description" : "SAML role list", + "protocol" : "saml", + "attributes" : { + "consent.screen.text" : "${samlRoleListScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "e48e57e3-cab0-447f-9dea-4f12cc471e83", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ] + }, { + "id" : "01c72e8e-de6c-42a4-bb1d-0aa00148e846", + "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" : "5370afb6-dd16-4cbc-b722-6ed7014db562", + "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" : "cab5af39-ab29-46cc-91da-112a711d189c", + "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" : "e9a43bbd-f7bd-4e50-9895-67af6b5e80d1", + "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" : "3e157e13-df03-4e22-a14e-4a35f90890fb", + "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" : "c859a67a-6f9c-4f87-b604-05e6c784997d", + "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" : "99f8dbdb-f392-4f59-a246-64145761a8fa", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-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" : "f3bbd325-2cc6-44fd-9abe-a6304888ca10", + "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" : "66124cb4-172c-4214-af16-e2de99a379df", + "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" : "fa813d0d-4980-407f-a67c-8dd5c375675c", + "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" : "627b6a59-0dbb-478f-9582-eaee738c46f7", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-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" : "3528314f-c06c-4652-b3ab-9ad2fa4e840e", + "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" : "1b8f605b-0899-486d-b021-963d9798c3ec", + "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" : "dda644f4-753e-4ab8-a5b3-92c27767bbd3", + "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" : "a1e1567a-b71e-4125-b158-732047ec6e33", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-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" : "c10bce57-3ed6-473c-857b-9073b1124a80", + "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" : "5b9b8e1a-b9ab-4ea1-a34d-c2197f26d2f6", + "name" : "allowed web origins", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-allowed-origins-mapper", + "consentRequired" : false, + "config" : { } + } ] + }, { + "id" : "e1a7cdc7-dd0f-4e37-92f5-771c0e81e4df", + "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" : "cdcaeeb3-149d-4e67-9ba0-e49fec6c086f", + "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" : "70e7a4f1-c258-4c02-91ae-854a75ef220d", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-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" : "e2039b0a-0eb7-4b11-9c98-d8eaa7e90a7d", + "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" : "dd9aca68-a109-4fc1-9901-84e4fc8c5c42", + "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" : "8d458c7f-f179-4aad-9dc6-8ea9a55b4810", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + }, { + "id" : "bddc332e-5caa-48a6-b709-19876d929b16", + "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" : "ccc82be9-7de5-461a-8fd5-e7a778a37450", + "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" : "e3232e42-eedf-4aa5-976c-54724fa45d1e", + "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" : "245f2381-e77e-4a7c-bc73-a3bec6c67458", + "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" : "5532e7c5-a264-4309-963d-206d96b7efe7", + "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" : "61065a36-9180-401d-8e43-38dd44d6e3bd", + "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" : "16291c95-d246-4750-93f0-e83a84d7e49e", + "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" : "af6fb6e0-8589-40ad-9cbf-b35e8b63107b", + "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" : "f1ccdc08-f381-46b3-ae93-cdfe4d916027", + "name" : "acr loa level", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-acr-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "1df1b503-5214-4fb5-9264-0cee84ee4f80", + "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" : "47762f90-b95f-41f0-8da7-91e84504fa20", + "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" : "315633ce-ba89-4ca9-87f1-d8c34a8911f1", + "name" : "upn", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-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" + } + } ] + } ], + "defaultDefaultClientScopes" : [ "role_list", "profile", "email", "roles", "web-origins", "acr" ], + "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" : "9ba92888-b2a6-4be4-a89c-a3f05ebb1313", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "ac2fec4c-f5db-4354-bb7c-5d87900f2f77", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "6a146739-2376-4137-99ae-de9147638087", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "35d04fd7-73be-457b-b050-0c38ed11843b", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-property-mapper", "oidc-address-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper" ] + } + }, { + "id" : "2ac5cb9d-8c2b-4368-bbd8-6cbe3424b263", + "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-role-list-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper" ] + } + }, { + "id" : "cf15c7a1-b0f1-400b-ab02-16edec74c8f9", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "acb58248-937a-4e65-85d3-468d105177cb", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "54592ef2-d85a-42ce-928e-a77ffe44cda6", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + } ], + "org.keycloak.keys.KeyProvider" : [ { + "id" : "82a8977a-4334-4f6c-bd9b-5856ec599d3a", + "name" : "hmac-generated", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "f0153e45-2edb-4e6b-a0d2-f607a09f88a5" ], + "secret" : [ "hQEZTRGyxn_c8GbKA8rnSaxvxZ8VPw8mtEfervY-Rczk-6DUz17GpYIkrBof3rYVHzH2d19boSL05bcM1XbUhA" ], + "priority" : [ "100" ], + "algorithm" : [ "HS256" ] + } + }, { + "id" : "1889c2b0-af3d-4549-9f52-57cd45d8220c", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEowIBAAKCAQEAqfjLiZLlukiznvQPUHZ8IKG4ymk5+YB5tmfKrAGdI/jsCBMIWldy47cr+tImmIKdOj+N9F7eckY/BuKOEbdBrwMBRyLN/hrM9r8gwYsu/euGxjHyDrkpsTed+M1xNfhZ1I0/00MHKyKV/eKzdwY9d2cWIzxZB7MGXP5M8e5kW4czuOVcNEzadjdPW23CNKFo0Lox/c+W/as/7sGGF55FpyfqAqGQxpRgZagGlxHGiGUxJ5DGpEdtiscg+OAo136+uZLPpNj8hP+DIli3BwYzNsgNKeUKpV8pmhmaOxm3hp80wEvmWxCZhWbjJDgQWD01dp89yq7IB2uIsGVC0tSs9QIDAQABAoIBADm7W8baslTXpMr0ss7tr7OVuqJlo19vl+ew0VIjKjCxt9n2PPwSf9+As9t5zco3cxf5xkmef4fo/DdmdELoL9M1/hUfaUBJ8hxNRt72W3u7qAdhp4oAsnyTG4EKps1iEYD0iR1EwwaPtMqLWdGvuOj5hrdpJARNdnfXmGMESeocL7A0RXdrR+K+xoYn9cIDjJ3kJE18xR5u1HttZQpUZI+K4BIyLdkPu6aJFdOh8Y27PE+3Yn8rb2ykikoTwO/7aj5rPNQXvXo8pj3eCwLEiE3g0aZX2NK+aAyfDPGxHnCZ0fMycmzyDR1CQct3TbPT5+krPmulDPrIEyW7NGBmH/ECgYEA5vvlXVAbRf1crlfQWH2WoKenzi2fVCCoEy70t0yx5k6hXJ+YWNqfjbRfOo1k9yPXU37ae7D4RE5XwOqolxDpZo3zA5U8duQntIOt5BmE+4qyS6X8VpjB3RgiIFIBQGKtkaHC/M3SxPrZ5ut06rt0K7erfCdfADbVXkrdt3+MzNsCgYEAvGFRoTB0wCaGtQOh4Ejx3VnHbYA5nZaJyd2Kpt3EgGv9p8eR7259wx4pgvqLB/qOlBF2L9N0KaYxj6Mlu2kOw3i0yFewj4q82DSJsUqGkHlVA4mYk+kElja31nUltl+DYzYJg8G5XgxryGdlPmra2AFvOt2OVfZXiPSdL9URrm8CgYEAxYwV5DKIwNkplOoBhE0UsB3zREB8jcTIOm/kV4g+dgw1sTPFZejEoLrs3vTirwN2OzC4xyTZkAG4x4Np4JlUJKOufRf7eGs1Egu0gurYcxFx34T8RUusMd1cAmxgKaK7c1v3maKmalVoWzhw6/iaKHGTNkGt3E8JOPWqni92ShUCgYAuT/6xkigh1VboyavSaByOPrQ4x31isM/PQRgFTiAxMlt6FCZcpt1kStYJzW7A12iWHnTf7Sxx0Nn+Zi2wlXN7uwE2/9f4cjNbNA9l9tx+SFYOOJW6R19JTsqDful2nKTAj1hnfAkGhic5bbIGVl7XHAMshauolpeOpBTA3bErIQKBgGzAxsaZiEYRLTQi3gC0C2eehSZKg60EViSi2aMaQrqvb+TEolS8LPvclhrAyxc76W3NmxVWorle/lYonALQkoUGEhVBk0ls42/poZPUR2+zDqmklfhdvGvYchah5UpnORvSC0/sKoYBJhT21wHCW6BmToROlu1N2rd1/bZuSC9E" ], + "keyUse" : [ "SIG" ], + "certificate" : [ "MIICmzCCAYMCBgGJS3vyuTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjMwNzEyMTkwMTAxWhcNMzMwNzEyMTkwMjQxWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCp+MuJkuW6SLOe9A9QdnwgobjKaTn5gHm2Z8qsAZ0j+OwIEwhaV3Ljtyv60iaYgp06P430Xt5yRj8G4o4Rt0GvAwFHIs3+Gsz2vyDBiy7964bGMfIOuSmxN534zXE1+FnUjT/TQwcrIpX94rN3Bj13ZxYjPFkHswZc/kzx7mRbhzO45Vw0TNp2N09bbcI0oWjQujH9z5b9qz/uwYYXnkWnJ+oCoZDGlGBlqAaXEcaIZTEnkMakR22KxyD44CjXfr65ks+k2PyE/4MiWLcHBjM2yA0p5QqlXymaGZo7GbeGnzTAS+ZbEJmFZuMkOBBYPTV2nz3KrsgHa4iwZULS1Kz1AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHaPo9Q4BPq6Wz6JwLZoP5i+WEkBBc4F07rHwwUbc5oDa5SOrNiA3VdL3peTHxWdECvsT+16ilPsRxM/BMzAF8GqVDpPLFc9H6h6QE68Sz2yT2h/P/ysmN4okjvF/7WkvDTJoYLJF2TS0efCNQGexMH1BNgfZDRQMFLRDSLcmvtTHwd7xTakskuIdyJPbUXGdS0npXuy9p1ioaN6Dm2OWjgtMCvOQvz5/dIGYRJxs5sIn0Na7TiuhTSlqDeMFFRvfqFgNexw56LlIvoeVDtrK5HYVeXp0AzRh6NgeqwzHCJj1uMTW3mdSVvqx8S8NfOvtQKpUis682b98WQc6Uf+6Ts=" ], + "priority" : [ "100" ] + } + }, { + "id" : "d4954e71-676c-49e3-a4e8-ad69d3d99574", + "name" : "rsa-enc-generated", + "providerId" : "rsa-enc-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEowIBAAKCAQEArqJVFuQEtNPmjljw8HlHy6bv2feBHufSPwxstJMT/b2hZ137sfGK9MvpQ6Wqez67qx7W1eDwxa6fxsWGwKw68C5CUOeTAs+l6XPaf7Ctrf5K4h0T98spUDys6Nei7flzvEQ+Nme+TEH/HE+a/MzNu1oWVniSwBK5WlQKNsGxxGvFCCwUT7UNMWGgl/wTdsoVWlSHC/Zm9C2x9p2mttpslFOw1CL3vN+g5Kw4n0fUNTSTGlxEK7eQRVDvXCWoI4pbdeebgU8J/aOYTysBBmt2l/YYDJM3KKGznXNsCmv/hqje2gPBHVIYNhriiJI4QOsSEFlTyNGuk/LhmTJ/QcMWpwIDAQABAoIBAA6xDnqGBVVXLGLWXbLFaUJbUXtjZKP+ecQfHfgVFY33yZ/iGr4uJXQRwZaU1eJXdT9gsU8+BNOErOFylbMY6j5xjdezm70VTg51VjD+4qWsKo2aR6dFmryq1hsipQzjOxbgIOG/2ZUdykIN+mqBKl+0JQPyUdpB2QEd59wScIunJ8g1YecsQx0SIeE7H1boHgvBPYCuf79WzsymcDbkhBvgv9yv8l7hXS1eJ415lVx6hV1Dzr/bbJAzAu2AnXv0X57GmNMcyjJEiDxhl8Fay89Xfq1YIvjLK81sMFTmB2KTBMbLUnbJWV3eAQ+/umnIzUOo7g9FIcoOphbnSSjeT4kCgYEA3Rdpya+f2ST/K8xNooHaEHuFprD/a2FvFS0fwdeJkcexkFrUbVIsnqpyBinbEQh7baivcqwYVAZ0YTT8S50Zg7dKwpAl/j4zUbeTSrwJY8SrS2m+wpDW0jbTUybTKFGjS04zZ3CM6tmogSDUSeeGYK3z1PnkFElBTk+X7TUj8+kCgYEAyjUZNMDm96wHILbtKrpR4CYjBYEPzbrKBzXCSz0G74kyugCj5vxp4F4+JcDweREx4BvKxBhrg6y3CGIatoGSdKchqPf1DS88J/9x0VDtdAX1P5ueUypevLFDr89/qV/b+wz1Xg6/1JjoFm4LC9Ulf1U/UYdAkrECII2J8fJF7A8CgYEAv8MN+2P7xjCjrk5ey+PKyt8IVkNQ1sdEvN5NnCihZrMI3McbVtKeZuQ5UAU/v+9Wdw+HVXPVChQrHyEA72iMd8Uj78ttWK6Efo02EO01S7aKSDeowEM2QFBTTNzw6xicBLYIOeDSKOSulYlu98b7s6FNSt2PqNS88vpwMMsVqvkCgYABmFuji+YGjCfePTMvxBqDPynFkFgUkmWnmuf2efvFBfsNdpXUa6dWKsgouhXrjpQrJWz7EQpAFqu2+Dcnu2vxWaQtVg9r1DSQSDaYpR/Ka4Wcw9iC5XGr4WYcS/HA30239Ek3PbyLq80g6CtUI5FRKNYACaYbwiO3KAavju64RwKBgBvw3xAwh9JdinAVBiYLEnLLsZKFXief6s09deua1M1LClVpfsX4yCAqzSVEAbyo045wsF9zv6MqW8dhepM8z+aPYG2ZrWdUgmyBPT3suAO/X9UhUjG9rEOP1CSo88WAglyFXHMKhb9+i2t3ruX859At+8bsa35rq7L2bHUi23Un" ], + "keyUse" : [ "ENC" ], + "certificate" : [ "MIICmzCCAYMCBgGJS3vzVTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjMwNzEyMTkwMTAxWhcNMzMwNzEyMTkwMjQxWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCuolUW5AS00+aOWPDweUfLpu/Z94Ee59I/DGy0kxP9vaFnXfux8Yr0y+lDpap7PrurHtbV4PDFrp/GxYbArDrwLkJQ55MCz6Xpc9p/sK2t/kriHRP3yylQPKzo16Lt+XO8RD42Z75MQf8cT5r8zM27WhZWeJLAErlaVAo2wbHEa8UILBRPtQ0xYaCX/BN2yhVaVIcL9mb0LbH2naa22myUU7DUIve836DkrDifR9Q1NJMaXEQrt5BFUO9cJagjilt155uBTwn9o5hPKwEGa3aX9hgMkzcoobOdc2wKa/+GqN7aA8EdUhg2GuKIkjhA6xIQWVPI0a6T8uGZMn9BwxanAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAK0EqiDnyfkBSiobCV8XD4UR860b5kszGrl9BI98LTEl9x8FW7stgjnFq/2oH8gUNHyqSgmdodSUxoBFTj8y9PtGM9eXCZug0o9oE89vBlvrqX5hTzb72hgtmdKyiWS9fV/Q+gb7I0OobzVwjje+JzXpWyJdkr7JEZiRE7UkK8y93UzQQ5/B3YfIdrY1z3OMpV5U2hEN/Hi8Nvn9nEEFuljLiDrK0mTKg7Wy1clGZtsxtTWtbWvh4ZvyXYox9+1pP0IuCAnZ7LrZ4RXQpYBjrzHTdUN/MC7YybbSH293w5oW9c8jaknqA1vIP1Zt9wKiEPufaaOYs+pcyPS5UZ18CIo=" ], + "priority" : [ "100" ], + "algorithm" : [ "RSA-OAEP" ] + } + }, { + "id" : "54f76d12-fcc0-4ec6-9ab2-45188ffcea14", + "name" : "aes-generated", + "providerId" : "aes-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "34a43cbd-3750-4f07-a148-1f40ac064c98" ], + "secret" : [ "3IAZ3ip5NgD86luRyGK40w" ], + "priority" : [ "100" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "4ac64979-6271-41ae-847a-8852a40149bc", + "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" : "e321e537-97ed-4e50-a58c-15c5384924f5", + "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" : "2d0d47f3-eed3-4f44-8791-84f00c1a9449", + "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" : "6c791ca8-8188-4a79-806d-bcd5a9db8cc9", + "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" : "71820ab0-d20e-44f1-ae42-9fed2cd6f628", + "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" : "a0bb78eb-d1c2-45eb-90a1-36d1e0c7db56", + "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" : "9e93a2c3-7b4d-48b2-a186-1685c6b0360b", + "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" : "23f1a829-98bf-44bc-97f7-adae78ab9acf", + "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" : "9b553882-44ef-43db-8c15-120dd17222bc", + "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" : "1f2a67ff-e896-4b23-80ce-5fd475a330e4", + "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" : "999da8eb-22e2-4d1e-a53f-40081b4e05ec", + "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" : "c0dca267-78b3-40e7-952b-9df7b6e882e0", + "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" : "bace84aa-80d4-4a4c-affc-a17179df57a7", + "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" : "b56c1523-2b9b-4cd6-a096-befa28f9f0cf", + "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" : "0e2cfce1-ddb5-49eb-95a3-b186c8129c8f", + "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" : "588b117f-d84a-4113-ba51-9e247cfa0fec", + "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 + }, { + "authenticator" : "registration-terms-and-conditions", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 70, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "84342493-6b26-4663-891b-93608f2bb590", + "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" : "ee4eb7ca-226e-437d-95d8-f2af42101acd", + "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" : "0555ea2e-bd0e-461e-b90b-1e29b5ac35b6", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "3bc5619d-216e-4a7a-b5fc-f63c319d48bc", + "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", + "parRequestUriLifespan" : "60", + "cibaInterval" : "5", + "realmReusableOtpCode" : "false" + }, + "keycloakVersion" : "22.0.0", + "userManagedAccessAllowed" : false, + "clientProfiles" : { + "profiles" : [ ] + }, + "clientPolicies" : { + "policies" : [ ] + } +} \ No newline at end of file diff --git a/src/test/resources/import-files/roles/71.1_import_realm_with_nested_composites.json b/src/test/resources/import-files/roles/71.1_import_realm_with_nested_composites.json index 7fcb148e3..8d7365bad 100644 --- a/src/test/resources/import-files/roles/71.1_import_realm_with_nested_composites.json +++ b/src/test/resources/import-files/roles/71.1_import_realm_with_nested_composites.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithRoles71", + "internationalizationEnabled": true, "roles": { "realm": [ { diff --git a/src/test/resources/import-files/roles/71.2_import_realm_with_nested_composites.json b/src/test/resources/import-files/roles/71.2_import_realm_with_nested_composites.json index b09a4389e..0ac57ac21 100644 --- a/src/test/resources/import-files/roles/71.2_import_realm_with_nested_composites.json +++ b/src/test/resources/import-files/roles/71.2_import_realm_with_nested_composites.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithRoles71", + "internationalizationEnabled": true, "roles": { "realm": [ { diff --git a/src/test/resources/import-files/roles/71.3_import_realm_with_nested_composites.json b/src/test/resources/import-files/roles/71.3_import_realm_with_nested_composites.json index 4b5bcaa01..05e0a8632 100644 --- a/src/test/resources/import-files/roles/71.3_import_realm_with_nested_composites.json +++ b/src/test/resources/import-files/roles/71.3_import_realm_with_nested_composites.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithRoles71", + "internationalizationEnabled": true, "roles": { "realm": [ { diff --git a/src/test/resources/import-files/users/00_create_realm_with_user.json b/src/test/resources/import-files/users/00_create_realm_with_user.json index 6d40537b7..6a3562e2e 100644 --- a/src/test/resources/import-files/users/00_create_realm_with_user.json +++ b/src/test/resources/import-files/users/00_create_realm_with_user.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithUsers", + "internationalizationEnabled": true, "users": [ { "username": "myuser", diff --git a/src/test/resources/import-files/users/01_update_realm_add_clientuser.json b/src/test/resources/import-files/users/01_update_realm_add_clientuser.json index c79b269f1..28a2125de 100644 --- a/src/test/resources/import-files/users/01_update_realm_add_clientuser.json +++ b/src/test/resources/import-files/users/01_update_realm_add_clientuser.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithUsers", + "internationalizationEnabled": true, "users": [ { "username": "myuser", diff --git a/src/test/resources/import-files/users/02.1_update_realm_change_clientusers_password.json b/src/test/resources/import-files/users/02.1_update_realm_change_clientusers_password.json index 073f35cbe..9c99b74db 100644 --- a/src/test/resources/import-files/users/02.1_update_realm_change_clientusers_password.json +++ b/src/test/resources/import-files/users/02.1_update_realm_change_clientusers_password.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithUsers", + "internationalizationEnabled": true, "users": [ { "username": "myuser", diff --git a/src/test/resources/import-files/users/02.2_update_realm_change_clientusers_password.json b/src/test/resources/import-files/users/02.2_update_realm_change_clientusers_password.json index 6e3123d2e..008318e42 100644 --- a/src/test/resources/import-files/users/02.2_update_realm_change_clientusers_password.json +++ b/src/test/resources/import-files/users/02.2_update_realm_change_clientusers_password.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithUsers", + "internationalizationEnabled": true, "users": [ { "username": "myuser", diff --git a/src/test/resources/import-files/users/50.1_create_realm_with_email_as_username_without_username.json b/src/test/resources/import-files/users/50.1_create_realm_with_email_as_username_without_username.json index c8bfc42f7..177d003e5 100644 --- a/src/test/resources/import-files/users/50.1_create_realm_with_email_as_username_without_username.json +++ b/src/test/resources/import-files/users/50.1_create_realm_with_email_as_username_without_username.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithUsers", + "internationalizationEnabled": true, "registrationAllowed": true, "registrationEmailAsUsername": true, "users": [ diff --git a/src/test/resources/import-files/users/50.2_update_realm_with_email_as_username_without_username.json b/src/test/resources/import-files/users/50.2_update_realm_with_email_as_username_without_username.json index adb73e8fd..058df39a7 100644 --- a/src/test/resources/import-files/users/50.2_update_realm_with_email_as_username_without_username.json +++ b/src/test/resources/import-files/users/50.2_update_realm_with_email_as_username_without_username.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithUsers", + "internationalizationEnabled": true, "registrationAllowed": true, "registrationEmailAsUsername": true, "users": [ diff --git a/src/test/resources/import-files/users/50.3_update_realm_with_email_as_username_with_invalid_username.json b/src/test/resources/import-files/users/50.3_update_realm_with_email_as_username_with_invalid_username.json index 295162e58..ccd14e472 100644 --- a/src/test/resources/import-files/users/50.3_update_realm_with_email_as_username_with_invalid_username.json +++ b/src/test/resources/import-files/users/50.3_update_realm_with_email_as_username_with_invalid_username.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithUsers", + "internationalizationEnabled": true, "registrationAllowed": true, "registrationEmailAsUsername": true, "users": [ diff --git a/src/test/resources/import-files/users/50.4_update_realm_with_email_as_username_with_correct_username.json b/src/test/resources/import-files/users/50.4_update_realm_with_email_as_username_with_correct_username.json index 213bd6d8f..a7c2bc42c 100644 --- a/src/test/resources/import-files/users/50.4_update_realm_with_email_as_username_with_correct_username.json +++ b/src/test/resources/import-files/users/50.4_update_realm_with_email_as_username_with_correct_username.json @@ -1,6 +1,7 @@ { "enabled": true, "realm": "realmWithUsers", + "internationalizationEnabled": true, "registrationAllowed": true, "registrationEmailAsUsername": true, "users": [