diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 67341cb..bbd220d 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -10,6 +10,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/* + - name: Install Playwright Browsers + run: npx playwright install --with-deps - name: Set up JDK 17 uses: actions/setup-java@v4 with: @@ -17,4 +22,4 @@ jobs: java-version: '17' cache: maven - name: Build project with Maven - run: mvn -B clean package + run: mvn -B clean verify diff --git a/README.md b/README.md index fdc27ea..ce8a3c4 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,17 @@ This Repository contains free to use Extensions for the OpenSource Project [Keycloak](https://github.com/keycloak/keycloak) -Contained Extensions: - -* Rest-Endpoints - * GetUsersByIdResource -> /admins/realms//users-by-id - * QueryParams: - * briefRepresentation true | false - * listWithIds List containing Ids of Users - * Returns List of Users +This repo contains the following extensions: + +## Authenticator-Required-Action + +You can add this Authenticator to your flow, so a User gets the defined Required-Action set on signing in. +[README.md - Authenticator-Required Action](./authenticator-required-action/README.md) + +## Rest-Endpoints + +* GetUsersByIdResource -> /admins/realms//users-by-id + * QueryParams: + * briefRepresentation true | false + * listWithIds List containing Ids of Users + * Returns List of Users diff --git a/authenticator-required-action/README.md b/authenticator-required-action/README.md new file mode 100644 index 0000000..a706c5b --- /dev/null +++ b/authenticator-required-action/README.md @@ -0,0 +1,20 @@ +# Authenticator-Required-Action +Imagine a user authenticates via an Identity Provider (IdP) and requires a specific action, such as resetting their password or agreeing to new terms of service. +This extension ensures that the configured required action is automatically set for the user once they authenticate through the Identity Provider. +```mermaid +flowchart LR + CompanyA(RealmCompanyA)-->UsersA + CompanyB(RealmCompanyB)-->UsersB + UsersA-- Connected via Idp alias: CompanyA ---RealmConciso + UsersB-- Connected via Idp alias: CompanyB ---RealmConciso +``` + +The First Broker login of Idp CompanyA is configured to set the 'TERMS_AND_CONDITIONS' for all users from CompanyA. Users from CompanyB dont have to accept the terms, so they dont get that action. + +## How to use +![required-action-flow.png](../docs/pics/required-action-flow.png) + +![required-action-authenticator-config.png](../docs/pics/required-action-authenticator-config.png) + +To see your available Required-Actions, go to Realm 'master' -> Provider info -> Search for 'req' or scroll down until you see 'required-action' in the column for SPI +![required-action-available-required-actions.png](../docs/pics/required-action-available-required-actions.png) diff --git a/authenticator-required-action/pom.xml b/authenticator-required-action/pom.xml new file mode 100644 index 0000000..4991490 --- /dev/null +++ b/authenticator-required-action/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + de.conciso.keycloak-extensions + parent + 1.0-SNAPSHOT + + + authenticator-required-action + + + UTF-8 + + + + + + org.keycloak + keycloak-core + + + org.keycloak + keycloak-server-spi + + + org.keycloak + keycloak-server-spi-private + + + org.keycloak + keycloak-services + + + com.microsoft.playwright + playwright + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + + diff --git a/authenticator-required-action/src/main/java/de/conciso/keycloak/authentication/required_action/RequiredActionAuthenticator.java b/authenticator-required-action/src/main/java/de/conciso/keycloak/authentication/required_action/RequiredActionAuthenticator.java new file mode 100644 index 0000000..c8082b4 --- /dev/null +++ b/authenticator-required-action/src/main/java/de/conciso/keycloak/authentication/required_action/RequiredActionAuthenticator.java @@ -0,0 +1,95 @@ +package de.conciso.keycloak.authentication.required_action; + +import jakarta.ws.rs.core.Response; +import org.jboss.logging.Logger; +import org.keycloak.authentication.AuthenticationFlowContext; +import org.keycloak.authentication.AuthenticationFlowError; +import org.keycloak.authentication.Authenticator; +import org.keycloak.events.Errors; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RequiredActionProviderModel; +import org.keycloak.models.UserModel; +import org.keycloak.sessions.AuthenticationSessionModel; + +import java.util.Optional; + +public class RequiredActionAuthenticator implements Authenticator { + private static final Logger LOGGER = Logger.getLogger(RequiredActionAuthenticator.class); + private static final String LOG_ERROR_MESSAGE_MISSING_AUTH_CONFIG = "AuthenticatorConfig is missing on RequiredActionAuthenticator"; + private static final String HTML_ERROR_MESSAGE = LOG_ERROR_MESSAGE_MISSING_AUTH_CONFIG + "!\nPlease contact your administrator"; + private static final String LOG_ERROR_MESSAGE_NON_EXISTENT_REQUIRED_ACTION = "AuthenticatorConfig references an unknown RequiredAction, please double check if it really exists: 'NON_EXISTENT_REQUIRED_ACTION'"; + + + @Override + public void authenticate(AuthenticationFlowContext context) { + var authenticatorConfig = Optional.ofNullable( + context.getAuthenticatorConfig() + .getConfig() + .get(RequiredActionConstants.CONFIG_REQUIRED_ACTION_KEY)); + if (authenticatorConfig.isEmpty()) { + LOGGER.error(LOG_ERROR_MESSAGE_MISSING_AUTH_CONFIG); + context.getEvent() + .realm(context.getRealm()) + .client(context.getSession().getContext().getClient()) + .user(context.getUser()) + .error(Errors.INVALID_CONFIG); + context.failure(AuthenticationFlowError.INTERNAL_ERROR, + htmlErrorResponse(context, + LOG_ERROR_MESSAGE_MISSING_AUTH_CONFIG + HTML_ERROR_MESSAGE)); + } else if (!doesRequiredActionExists(context, authenticatorConfig.get())) { + LOGGER.error(LOG_ERROR_MESSAGE_NON_EXISTENT_REQUIRED_ACTION); + context.getEvent() + .realm(context.getRealm()) + .client(context.getSession().getContext().getClient()) + .user(context.getUser()) + .error(Errors.INVALID_CONFIG); + context.failure(AuthenticationFlowError.INTERNAL_ERROR, + htmlErrorResponse(context, + LOG_ERROR_MESSAGE_NON_EXISTENT_REQUIRED_ACTION + HTML_ERROR_MESSAGE)); + } else { + context.getUser().addRequiredAction(authenticatorConfig.get()); + context.success(); + } + } + + private boolean doesRequiredActionExists(AuthenticationFlowContext context, String providerId) { + var requiredAction = context.getRealm().getRequiredActionProvidersStream() + .map(RequiredActionProviderModel::getProviderId) + .filter(id -> id.equals(providerId)) + .findFirst(); + return requiredAction.isPresent(); + } + + private Response htmlErrorResponse(AuthenticationFlowContext context, String errorMessage) { + AuthenticationSessionModel authSession = context.getAuthenticationSession(); + return context.form() + .setError(errorMessage, authSession.getAuthenticatedUser().getUsername(), + authSession.getClient().getClientId()) + .createErrorPage(Response.Status.INTERNAL_SERVER_ERROR); + } + + @Override + public void action(AuthenticationFlowContext context) { + } + + @Override + public boolean requiresUser() { + return true; + } + + @Override + public boolean configuredFor(KeycloakSession keycloakSession, RealmModel realmModel, UserModel userModel) { + return true; + } + + @Override + public void setRequiredActions(KeycloakSession keycloakSession, RealmModel realmModel, UserModel userModel) { + //intentionally empty + } + + @Override + public void close() { + + } +} diff --git a/authenticator-required-action/src/main/java/de/conciso/keycloak/authentication/required_action/RequiredActionAuthenticatorFactory.java b/authenticator-required-action/src/main/java/de/conciso/keycloak/authentication/required_action/RequiredActionAuthenticatorFactory.java new file mode 100644 index 0000000..5ad0bc8 --- /dev/null +++ b/authenticator-required-action/src/main/java/de/conciso/keycloak/authentication/required_action/RequiredActionAuthenticatorFactory.java @@ -0,0 +1,88 @@ +package de.conciso.keycloak.authentication.required_action; + +import org.keycloak.Config; +import org.keycloak.authentication.Authenticator; +import org.keycloak.authentication.AuthenticatorFactory; +import org.keycloak.models.AuthenticationExecutionModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.provider.ProviderConfigProperty; + +import java.util.List; + +public class RequiredActionAuthenticatorFactory implements AuthenticatorFactory { + + public static final String PROVIDER_ID = "required-action-authenticator"; + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public String getDisplayType() { + return "Set Required-Action Authentication"; + } + + @Override + public String getReferenceCategory() { + return "required-action"; + } + + @Override + public boolean isConfigurable() { + return true; + } + + @Override + public AuthenticationExecutionModel.Requirement[] getRequirementChoices() { + return new AuthenticationExecutionModel.Requirement[]{ + AuthenticationExecutionModel.Requirement.REQUIRED, + AuthenticationExecutionModel.Requirement.DISABLED}; + } + + @Override + public boolean isUserSetupAllowed() { + return false; + } + + @Override + public String getHelpText() { + return "Sets the configured RequiredAction for the authenticating User"; + } + + @Override + public List getConfigProperties() { + //TODO @Robin Maybe multivalued in the future ? + return List.of( + new ProviderConfigProperty( + RequiredActionConstants.CONFIG_REQUIRED_ACTION_KEY, + "Required Action", + "Specifies the Required Action, that will be assigned to the authenticating User", + ProviderConfigProperty.STRING_TYPE, + "", + false, + true) + ); + } + + @Override + public Authenticator create(KeycloakSession keycloakSession) { + return new RequiredActionAuthenticator(); + } + + @Override + public void init(Config.Scope scope) { + + } + + @Override + public void postInit(KeycloakSessionFactory keycloakSessionFactory) { + + } + + @Override + public void close() { + + } +} diff --git a/authenticator-required-action/src/main/java/de/conciso/keycloak/authentication/required_action/RequiredActionConstants.java b/authenticator-required-action/src/main/java/de/conciso/keycloak/authentication/required_action/RequiredActionConstants.java new file mode 100644 index 0000000..c6fc751 --- /dev/null +++ b/authenticator-required-action/src/main/java/de/conciso/keycloak/authentication/required_action/RequiredActionConstants.java @@ -0,0 +1,5 @@ +package de.conciso.keycloak.authentication.required_action; + +public final class RequiredActionConstants { + public static final String CONFIG_REQUIRED_ACTION_KEY = "REQUIRED_ACTION"; +} diff --git a/authenticator-required-action/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory b/authenticator-required-action/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory new file mode 100644 index 0000000..1c59fc5 --- /dev/null +++ b/authenticator-required-action/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory @@ -0,0 +1 @@ +de.conciso.keycloak.authentication.required_action.RequiredActionAuthenticatorFactory diff --git a/authenticator-required-action/src/test/java/de/conciso/keycloak/authentication/required_action/RequiredActionAuthenticatorIT.java b/authenticator-required-action/src/test/java/de/conciso/keycloak/authentication/required_action/RequiredActionAuthenticatorIT.java new file mode 100644 index 0000000..c074793 --- /dev/null +++ b/authenticator-required-action/src/test/java/de/conciso/keycloak/authentication/required_action/RequiredActionAuthenticatorIT.java @@ -0,0 +1,205 @@ +package de.conciso.keycloak.authentication.required_action; + +import com.microsoft.playwright.Browser; +import com.microsoft.playwright.BrowserType; +import com.microsoft.playwright.Page; +import com.microsoft.playwright.Playwright; +import com.microsoft.playwright.options.AriaRole; +import dasniko.testcontainers.keycloak.KeycloakContainer; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.event.LoggingEvent; +import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.containers.output.WaitingConsumer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Stream; + +import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +@Testcontainers +class RequiredActionAuthenticatorIT { + private static final Logger LOGGER = LoggerFactory.getLogger(RequiredActionAuthenticatorIT.class); + private static final String KEYCLOAK_VERSION = System.getProperty("keycloak.version", "latest"); + private static final String REALM_NAME = "required-action"; + private static final String ADMIN_USER = "admin"; + private static final String ADMIN_PASS = "admin"; + private static final String AUTHENTICATOR_CONFIG_ID = "9b46ecb5-2b16-40f0-beae-4fc4ba905292"; + private static final String LOG_AUTHENTICATOR_CONFIG_MISSING_ERROR = "AuthenticatorConfig is missing on RequiredActionAuthenticator"; + private static final String LOG_AUTHENTICATOR_CONFIG_REFERENCES_NON_EXISTENT_REQUIRED_ACTION = "AuthenticatorConfig references an unknown RequiredAction, please double check if it really exists: 'NON_EXISTENT_REQUIRED_ACTION'"; + + @Container + private static final KeycloakContainer keycloak = + new KeycloakContainer("quay.io/keycloak/keycloak:" + KEYCLOAK_VERSION) + .withEnv("KEYCLOAK_ADMIN", ADMIN_USER) + .withEnv("KEYCLOAK_ADMIN_PASSWORD", ADMIN_PASS) + .withLogConsumer(new Slf4jLogConsumer(LOGGER).withSeparateOutputStreams()) + .withProviderClassesFrom("target/classes") + .withRealmImportFile("required-action-realm.json"); + + private static Stream provideUserLogins() { + return Stream.of( + Arguments.of("dieterbohlen", "dietersPassword", "TERMS_AND_CONDITIONS"), + Arguments.of("mannimammut", "mannimammutsPassword", "UPDATE_PASSWORD"), + Arguments.of("peterpommes", "peterpommesPassword", "UPDATE_PROFILE") + ); + } + + @ParameterizedTest + @MethodSource("provideUserLogins") + void testThatUsersHaveCorrectRequiredActionAfterLogin(String userName, String password, String requiredAction) { + // Setting the specific required action to be added to the Authentication Config + var authenticatorConfig = new AuthenticatorConfigRepresentation(); + authenticatorConfig.setId(AUTHENTICATOR_CONFIG_ID); + authenticatorConfig.setAlias("RequiredAction"); + var configMap = new HashMap(); + configMap.put("REQUIRED_ACTION", requiredAction); + authenticatorConfig.setConfig(configMap); + + var keycloakAdminClient = keycloak.getKeycloakAdminClient().realm(REALM_NAME); + keycloakAdminClient.flows().updateAuthenticatorConfig(AUTHENTICATOR_CONFIG_ID, authenticatorConfig); + + assertThat(keycloakAdminClient.users().searchByUsername(userName, true).get(0).getRequiredActions()) + .isEmpty(); + + executeBrowserFlow(userName, password, requiredAction); + } + + void executeBrowserFlow(String userName, String password, String requiredAction) { + + try (Playwright playwright = Playwright.create()) { + BrowserType chromium = playwright.chromium(); + // comment me in if you want to run in headless mode ! + //Browser browser = chromium.launch(new BrowserType.LaunchOptions().setHeadless(false)); + Browser browser = chromium.launch(); + Page page = browser.newPage(); + + loginUser(browser, page, userName, password); + + // split here, for the specific required action + switch (requiredAction) { + case "TERMS_AND_CONDITIONS": + page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Accept")).click(); + break; + case "UPDATE_PASSWORD": + page.getByLabel("New Password").fill("Test123!"); + page.getByLabel("Confirm Password").fill("Test123!"); + page.getByLabel("Confirm Password").press("Enter"); + break; + case "UPDATE_PROFILE": + assertThat(keycloak.getKeycloakAdminClient().realm(REALM_NAME).users().searchByUsername(userName, true).get(0).getRequiredActions()).containsExactly(requiredAction); + page.getByText("Submit").click(); + break; + default: + Assertions.fail(); + } + + page.waitForURL(String.format("%s/realms/required-action/account/#/security/signingin", keycloak.getAuthServerUrl())); + + assertThat(page.getByRole(AriaRole.HEADING, new Page.GetByRoleOptions().setName("Signing in")).first()).isVisible(); + + browser.close(); + } + } + + @Test + void testThatFlowIsNotSuccessFulWhenAuthenticatorConfigIsEmpty() throws TimeoutException { + // Setting the AuthenticatorConfig to empty + var authenticatorConfig = new AuthenticatorConfigRepresentation(); + authenticatorConfig.setId(AUTHENTICATOR_CONFIG_ID); + authenticatorConfig.setAlias("RequiredAction"); + var configMap = new HashMap(); + configMap.put("REQUIRED_ACTION", ""); + authenticatorConfig.setConfig(configMap); + + var keycloakAdminClient = keycloak.getKeycloakAdminClient().realm(REALM_NAME); + keycloakAdminClient.flows().updateAuthenticatorConfig(AUTHENTICATOR_CONFIG_ID, authenticatorConfig); + + try (Playwright playwright = Playwright.create()) { + BrowserType chromium = playwright.chromium(); + Browser browser = chromium.launch(); + Page page = browser.newPage(); + + loginUser(browser, page, "dieterbohlen", "dietersPassword"); + + assertThat(page.getByRole(AriaRole.HEADING, new Page.GetByRoleOptions().setName("We are sorry"))).isVisible(); + assertThat(page.getByText(LOG_AUTHENTICATOR_CONFIG_MISSING_ERROR)).isVisible(); + } + + final List logs = Arrays.stream(keycloak.getLogs().split("\n")).filter(i -> i.contains(LOG_AUTHENTICATOR_CONFIG_MISSING_ERROR)).toList(); + assertThat(logs).hasSize(1); + assertThat(logs.get(0)).contains( + "ERROR", + "[de.conciso.keycloak.authentication.required_action.RequiredActionAuthenticator]", + "AuthenticatorConfig is missing on RequiredActionAuthenticator" + ); + } + + @Test + void testThatErrorIsLoggedWhenAuthenticatorConfigReferencesNonExistentRequiredAction() { + final String NON_EXISTENT_REQUIRED_ACTION = "NON_EXISTENT_REQUIRED_ACTION"; + // Setting the AuthenticatorConfig to empty + var authenticatorConfig = new AuthenticatorConfigRepresentation(); + authenticatorConfig.setId(AUTHENTICATOR_CONFIG_ID); + authenticatorConfig.setAlias("RequiredAction"); + var configMap = new HashMap(); + configMap.put("REQUIRED_ACTION", NON_EXISTENT_REQUIRED_ACTION); + authenticatorConfig.setConfig(configMap); + + var keycloakAdminClient = keycloak.getKeycloakAdminClient().realm(REALM_NAME); + keycloakAdminClient.flows().updateAuthenticatorConfig(AUTHENTICATOR_CONFIG_ID, authenticatorConfig); + + try (Playwright playwright = Playwright.create()) { + BrowserType chromium = playwright.chromium(); + Browser browser = chromium.launch(); + Page page = browser.newPage(); + + loginUser(browser, page, "dieterbohlen", "dietersPassword"); + + assertThat(page.getByRole(AriaRole.HEADING, new Page.GetByRoleOptions().setName("We are sorry"))).isVisible(); + assertThat(page.getByText(LOG_AUTHENTICATOR_CONFIG_REFERENCES_NON_EXISTENT_REQUIRED_ACTION)).isVisible(); + } + + final List logs = Arrays.stream(keycloak.getLogs().split("\n")).filter(i -> i.contains(LOG_AUTHENTICATOR_CONFIG_REFERENCES_NON_EXISTENT_REQUIRED_ACTION)).toList(); + assertThat(logs).hasSize(1); + assertThat(logs.get(0)).contains( + "ERROR", + "[de.conciso.keycloak.authentication.required_action.RequiredActionAuthenticator]", + String.format("AuthenticatorConfig references an unknown RequiredAction, please double check if it really exists: '%s'", NON_EXISTENT_REQUIRED_ACTION) + ); + + } + + private void loginUser(Browser browser, Page page, String username, String password) { + page.navigate(String.format("%s/realms/required-action/account/", keycloak.getAuthServerUrl())); + + page.getByText("Signing in").click(); + page.waitForURL("**/realms/required-action/protocol/openid-connect/auth**"); + + // Login Page + page.getByLabel("Username or email").click(); + page.getByLabel("Username or email").fill(username); + + page.getByLabel("Password").first().fill(password); + page.getByLabel("Password").first().press("Enter"); + } +} + + + diff --git a/authenticator-required-action/src/test/resources/log4j2.properties b/authenticator-required-action/src/test/resources/log4j2.properties new file mode 100755 index 0000000..6f20fe4 --- /dev/null +++ b/authenticator-required-action/src/test/resources/log4j2.properties @@ -0,0 +1,27 @@ +status = error +name = PropertiesConfig + +filters = threshold + +filter.threshold.type = ThresholdFilter +filter.threshold.level = debug + +appenders = console, file + +appender.file.type = File +appender.file.name = LOGFILE +appender.file.fileName = target/test.log +appender.file.layout.type = PatternLayout +appender.file.layout.pattern = %r [%t] {%-5p} %c %notEmpty{%x }- %m%n +appender.file.layout.alwaysWriteExceptions=true + +appender.console.type = Console +appender.console.name = STDOUT +appender.console.layout.type = PatternLayout +appender.console.layout.pattern = %r [%t] %highlight{%-5p} %c %notEmpty{%x }- %m%n%ex{short}%n +appender.console.layout.alwaysWriteExceptions=false + +rootLogger.level = info +rootLogger.appenderRefs = stdout, file +rootLogger.appenderRef.stdout.ref = STDOUT +rootLogger.appenderRef.file.ref = LOGFILE \ No newline at end of file diff --git a/authenticator-required-action/src/test/resources/required-action-realm.json b/authenticator-required-action/src/test/resources/required-action-realm.json new file mode 100644 index 0000000..506cd73 --- /dev/null +++ b/authenticator-required-action/src/test/resources/required-action-realm.json @@ -0,0 +1,1888 @@ +{ + "id" : "6d1204b3-dd74-474f-be22-96839f19eed3", + "realm" : "required-action", + "notBefore" : 0, + "defaultSignatureAlgorithm" : "RS256", + "revokeRefreshToken" : false, + "refreshTokenMaxReuse" : 0, + "accessTokenLifespan" : 300, + "accessTokenLifespanForImplicitFlow" : 900, + "ssoSessionIdleTimeout" : 1800, + "ssoSessionMaxLifespan" : 36000, + "ssoSessionIdleTimeoutRememberMe" : 0, + "ssoSessionMaxLifespanRememberMe" : 0, + "offlineSessionIdleTimeout" : 2592000, + "offlineSessionMaxLifespanEnabled" : false, + "offlineSessionMaxLifespan" : 5184000, + "clientSessionIdleTimeout" : 0, + "clientSessionMaxLifespan" : 0, + "clientOfflineSessionIdleTimeout" : 0, + "clientOfflineSessionMaxLifespan" : 0, + "accessCodeLifespan" : 60, + "accessCodeLifespanUserAction" : 300, + "accessCodeLifespanLogin" : 1800, + "actionTokenGeneratedByAdminLifespan" : 43200, + "actionTokenGeneratedByUserLifespan" : 300, + "oauth2DeviceCodeLifespan" : 600, + "oauth2DevicePollingInterval" : 5, + "enabled" : true, + "sslRequired" : "external", + "registrationAllowed" : false, + "registrationEmailAsUsername" : false, + "rememberMe" : false, + "verifyEmail" : false, + "loginWithEmailAllowed" : true, + "duplicateEmailsAllowed" : false, + "resetPasswordAllowed" : false, + "editUsernameAllowed" : false, + "bruteForceProtected" : false, + "permanentLockout" : false, + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "804d1742-aaf9-409e-8b00-05b4d2e270d7", + "name" : "default-roles-required-action", + "description" : "${role_default-roles}", + "composite" : true, + "composites" : { + "realm" : [ "offline_access", "uma_authorization" ], + "client" : { + "account" : [ "view-profile", "manage-account" ] + } + }, + "clientRole" : false, + "containerId" : "6d1204b3-dd74-474f-be22-96839f19eed3", + "attributes" : { } + }, { + "id" : "2ce170cd-7c86-40e2-9d0f-95b1291a1992", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "composite" : false, + "clientRole" : false, + "containerId" : "6d1204b3-dd74-474f-be22-96839f19eed3", + "attributes" : { } + }, { + "id" : "240dd58e-89d2-49ba-a825-58dd2f736bf6", + "name" : "offline_access", + "description" : "${role_offline-access}", + "composite" : false, + "clientRole" : false, + "containerId" : "6d1204b3-dd74-474f-be22-96839f19eed3", + "attributes" : { } + } ], + "client" : { + "realm-management" : [ { + "id" : "9ca175c8-2a66-4b05-b2b4-c52873f9e9c9", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "query-users", "query-groups" ] + } + }, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "c9ad427a-5a07-42d5-9f6f-e32c6b067f58", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "0091b601-3e18-46d0-8f08-f08e9edbf24f", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "d761d28d-1b6d-4f3c-a752-9e6509f9331d", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "784ca7fc-e2ef-4297-8c7c-b17d3d468c81", + "name" : "realm-admin", + "description" : "${role_realm-admin}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "view-users", "manage-clients", "create-client", "query-realms", "manage-authorization", "view-events", "view-identity-providers", "view-authorization", "view-realm", "manage-events", "query-clients", "manage-identity-providers", "query-users", "query-groups", "manage-realm", "impersonation", "manage-users", "view-clients" ] + } + }, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "643e296a-0bb1-4dcb-a68a-f8ea49769189", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "16a748fa-767f-414d-9eee-f4ea861c3b10", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "72d41ecc-f412-4eb8-91ea-4eb65fcff477", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "d25034d5-0a0c-4c09-b6cc-a10717c3fd7d", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "34b9a683-5266-47d1-945a-91dc86365fde", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "257cc5fe-9af4-46b2-ac7e-75b322554a4c", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "614a905a-e950-4ecf-b508-b18963f6955c", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "987d1e58-f5f9-4dd5-a36f-24a881dbc96f", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "4c9aa670-b51e-4fcd-a0e1-09eaa72fb60e", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "c2e48179-563e-408c-a73a-6315e43f3dd0", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "527d8142-8b92-4626-8b42-297567b3cd65", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "1b0a4571-dcdb-41d6-b43a-93cd878c30dc", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "69137655-7229-4b50-94ce-62f4fd86948b", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + }, { + "id" : "38ae5226-3113-4498-839b-fbe271e540f6", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "attributes" : { } + } ], + "security-admin-console" : [ ], + "admin-cli" : [ ], + "account-console" : [ ], + "broker" : [ { + "id" : "1bbd06bc-8aa4-4e3a-8ee4-be78d2f78499", + "name" : "read-token", + "description" : "${role_read-token}", + "composite" : false, + "clientRole" : true, + "containerId" : "31eb8481-2800-4c8e-869b-dc579b26f3df", + "attributes" : { } + } ], + "account" : [ { + "id" : "cd5feec3-45e1-44c3-83fe-6f793455a3d8", + "name" : "manage-consent", + "description" : "${role_manage-consent}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "view-consent" ] + } + }, + "clientRole" : true, + "containerId" : "481ced1f-c380-4c4f-8b02-5e78ae4a2822", + "attributes" : { } + }, { + "id" : "994c1232-c6a6-486c-814d-67d66193f392", + "name" : "view-applications", + "description" : "${role_view-applications}", + "composite" : false, + "clientRole" : true, + "containerId" : "481ced1f-c380-4c4f-8b02-5e78ae4a2822", + "attributes" : { } + }, { + "id" : "7d882933-3a23-424c-bb34-cb737407604c", + "name" : "view-groups", + "description" : "${role_view-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "481ced1f-c380-4c4f-8b02-5e78ae4a2822", + "attributes" : { } + }, { + "id" : "3b4581a7-7bc9-4f1c-b3a9-957e46fffba0", + "name" : "view-profile", + "description" : "${role_view-profile}", + "composite" : false, + "clientRole" : true, + "containerId" : "481ced1f-c380-4c4f-8b02-5e78ae4a2822", + "attributes" : { } + }, { + "id" : "6d629beb-a790-4353-83a9-d826dea6b97c", + "name" : "manage-account-links", + "description" : "${role_manage-account-links}", + "composite" : false, + "clientRole" : true, + "containerId" : "481ced1f-c380-4c4f-8b02-5e78ae4a2822", + "attributes" : { } + }, { + "id" : "a997e7bf-01f3-4a01-89cd-a1aacf5f1020", + "name" : "view-consent", + "description" : "${role_view-consent}", + "composite" : false, + "clientRole" : true, + "containerId" : "481ced1f-c380-4c4f-8b02-5e78ae4a2822", + "attributes" : { } + }, { + "id" : "d83522dd-7a9d-4ca9-8129-3b073fe8b5d2", + "name" : "manage-account", + "description" : "${role_manage-account}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "manage-account-links" ] + } + }, + "clientRole" : true, + "containerId" : "481ced1f-c380-4c4f-8b02-5e78ae4a2822", + "attributes" : { } + }, { + "id" : "50fcba29-be64-4980-be93-e13dd043032b", + "name" : "delete-account", + "description" : "${role_delete-account}", + "composite" : false, + "clientRole" : true, + "containerId" : "481ced1f-c380-4c4f-8b02-5e78ae4a2822", + "attributes" : { } + } ] + } + }, + "groups" : [ ], + "defaultRole" : { + "id" : "804d1742-aaf9-409e-8b00-05b4d2e270d7", + "name" : "default-roles-required-action", + "description" : "${role_default-roles}", + "composite" : true, + "clientRole" : false, + "containerId" : "6d1204b3-dd74-474f-be22-96839f19eed3" + }, + "requiredCredentials" : [ "password" ], + "otpPolicyType" : "totp", + "otpPolicyAlgorithm" : "HmacSHA1", + "otpPolicyInitialCounter" : 0, + "otpPolicyDigits" : 6, + "otpPolicyLookAheadWindow" : 1, + "otpPolicyPeriod" : 30, + "otpPolicyCodeReusable" : false, + "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName" ], + "localizationTexts" : { }, + "webAuthnPolicyRpEntityName" : "keycloak", + "webAuthnPolicySignatureAlgorithms" : [ "ES256" ], + "webAuthnPolicyRpId" : "", + "webAuthnPolicyAttestationConveyancePreference" : "not specified", + "webAuthnPolicyAuthenticatorAttachment" : "not specified", + "webAuthnPolicyRequireResidentKey" : "not specified", + "webAuthnPolicyUserVerificationRequirement" : "not specified", + "webAuthnPolicyCreateTimeout" : 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyAcceptableAaguids" : [ ], + "webAuthnPolicyExtraOrigins" : [ ], + "webAuthnPolicyPasswordlessRpEntityName" : "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ], + "webAuthnPolicyPasswordlessRpId" : "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified", + "webAuthnPolicyPasswordlessCreateTimeout" : 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ], + "webAuthnPolicyPasswordlessExtraOrigins" : [ ], + "scopeMappings" : [ { + "clientScope" : "offline_access", + "roles" : [ "offline_access" ] + } ], + "clientScopeMappings" : { + "account" : [ { + "client" : "account-console", + "roles" : [ "manage-account", "view-groups" ] + } ] + }, + "clients" : [ { + "id" : "481ced1f-c380-4c4f-8b02-5e78ae4a2822", + "clientId" : "account", + "name" : "${client_account}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/required-action/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/required-action/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "5f71f314-d2df-4c86-b34f-3a03f81cfcfa", + "clientId" : "account-console", + "name" : "${client_account-console}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/required-action/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/required-action/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" : "d0c5344d-492e-44a4-af16-8ba21b9453d5", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "d65684a2-67c5-46bc-b40c-6249e460003b", + "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" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "31eb8481-2800-4c8e-869b-dc579b26f3df", + "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" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "940b769f-8de4-4b8d-86ed-a8f4acc8c252", + "clientId" : "realm-management", + "name" : "${client_realm-management}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "8a8c87e9-7338-4940-ae28-a624bd5bd9ff", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "rootUrl" : "${authAdminUrl}", + "baseUrl" : "/admin/required-action/console/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/admin/required-action/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" : "21066f66-c44e-42b5-b952-3139e3832b72", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + } ], + "clientScopes" : [ { + "id" : "8c818f6d-8f2b-4ecf-889e-119e54b42f0c", + "name" : "role_list", + "description" : "SAML role list", + "protocol" : "saml", + "attributes" : { + "consent.screen.text" : "${samlRoleListScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "6dbe57be-bd86-42e6-a6c3-72eb85c7e468", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ] + }, { + "id" : "61acfc87-863d-4b59-88b5-903ae6837d02", + "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" : "085bb380-2c42-4d0a-ad67-54a948ed1807", + "name" : "acr loa level", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-acr-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "userinfo.token.claim" : "true" + } + } ] + }, { + "id" : "d68267ae-53ee-448a-beb4-5d777491df30", + "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" : "78bfb0c2-0fe7-4413-8ef4-5d06a9f61a4b", + "name" : "address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-address-mapper", + "consentRequired" : false, + "config" : { + "user.attribute.formatted" : "formatted", + "user.attribute.country" : "country", + "introspection.token.claim" : "true", + "user.attribute.postal_code" : "postal_code", + "userinfo.token.claim" : "true", + "user.attribute.street" : "street", + "id.token.claim" : "true", + "user.attribute.region" : "region", + "access.token.claim" : "true", + "user.attribute.locality" : "locality" + } + } ] + }, { + "id" : "c5591fcd-10da-49ea-ae9c-c57258090d2a", + "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" : "b0bed8ec-ec4a-4c20-b112-f4cb79c6ed32", + "name" : "realm roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "multivalued" : "true", + "user.attribute" : "foo", + "access.token.claim" : "true", + "claim.name" : "realm_access.roles", + "jsonType.label" : "String" + } + }, { + "id" : "d345638c-5c78-460c-9bdf-5d845ac3aefa", + "name" : "client roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-client-role-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "multivalued" : "true", + "user.attribute" : "foo", + "access.token.claim" : "true", + "claim.name" : "resource_access.${client_id}.roles", + "jsonType.label" : "String" + } + }, { + "id" : "df4b585e-4b26-45dc-847f-a53cc2f6a7e3", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "194f945f-f039-4dc1-a6a6-3dc2543d1e24", + "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" : "bdaaf03c-4e69-4e66-8d42-c724d3c75b00", + "name" : "upn", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "upn", + "jsonType.label" : "String" + } + }, { + "id" : "e98bdc55-d276-48cf-89d2-447cd2aaf464", + "name" : "groups", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "multivalued" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "foo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "groups", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "837ffc86-a47f-473a-a409-43e0baf64fce", + "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" : "e8514d42-292d-4111-9827-f5d80a475b39", + "name" : "nickname", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "nickname", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "nickname", + "jsonType.label" : "String" + } + }, { + "id" : "cae698b2-9615-41ff-91a2-e2ed0e73bbac", + "name" : "website", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "website", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "website", + "jsonType.label" : "String" + } + }, { + "id" : "9621d327-71ca-4897-9404-a1061e2f29b2", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + }, { + "id" : "739227b7-c148-4ad0-9059-03f5aa4ea864", + "name" : "middle name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "middleName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "middle_name", + "jsonType.label" : "String" + } + }, { + "id" : "29282b67-9ee3-4c07-b7a7-433797f0fa4a", + "name" : "gender", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "gender", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "gender", + "jsonType.label" : "String" + } + }, { + "id" : "83df5c22-f874-4e37-a4ee-3da1ae6f528a", + "name" : "zoneinfo", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "zoneinfo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "zoneinfo", + "jsonType.label" : "String" + } + }, { + "id" : "38dab969-7d3f-4ced-81ca-306573707dd5", + "name" : "birthdate", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "birthdate", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "birthdate", + "jsonType.label" : "String" + } + }, { + "id" : "f4a103e3-63be-4717-86f3-1e85ec3bd0e6", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "userinfo.token.claim" : "true" + } + }, { + "id" : "93495e94-fc3e-4d18-b50e-e48fabbff72b", + "name" : "picture", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "picture", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "picture", + "jsonType.label" : "String" + } + }, { + "id" : "ffcc9388-15f0-499c-8147-910b1700cf4c", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "580c49c1-837c-4895-9fdc-6f216fb6d2a1", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "a8caecbc-d930-4838-9628-dde776243156", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "954a21b2-165c-4eba-8158-b4680092a35a", + "name" : "updated at", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "updatedAt", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "updated_at", + "jsonType.label" : "long" + } + }, { + "id" : "8d8c768f-15c5-4c47-94a0-5c5c41b84abd", + "name" : "profile", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "profile", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "profile", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "48af82a4-fe11-423c-ba3a-54777a1b82ec", + "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" : "86833e35-5b7c-4848-9dd5-6d0c4e765aa5", + "name" : "allowed web origins", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-allowed-origins-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "0656ec7e-4ba0-4e8a-a15a-6935c37a9b93", + "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" : "0ecbf793-ce72-4e9a-8d83-92f4eceb3c1c", + "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" : "34b9e41a-423f-4dd6-b942-37b71552d656", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + }, { + "id" : "1c596a45-f98e-4e35-bcd7-d7e0588517fa", + "name" : "email verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "emailVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email_verified", + "jsonType.label" : "boolean" + } + } ] + }, { + "id" : "fe13dc1c-16e0-4611-86e4-b4e2694830f7", + "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" : "16e7d078-f7f1-4846-9ec0-043f1cd87bf3", + "name" : "phone number", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumber", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number", + "jsonType.label" : "String" + } + }, { + "id" : "baba8fed-86ed-4f1c-9f31-fcbbecf2ee0b", + "name" : "phone number verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumberVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number_verified", + "jsonType.label" : "boolean" + } + } ] + } ], + "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", + "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "xXSSProtection" : "1; mode=block", + "strictTransportSecurity" : "max-age=31536000; includeSubDomains" + }, + "smtpServer" : { }, + "eventsEnabled" : false, + "eventsListeners" : [ "jboss-logging" ], + "enabledEventTypes" : [ ], + "adminEventsEnabled" : false, + "adminEventsDetailsEnabled" : false, + "identityProviders" : [ ], + "identityProviderMappers" : [ ], + "components" : { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ { + "id" : "cdedba02-9c4b-43ad-b638-6f37708d0fcd", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "db8eeff0-6c2b-496d-9710-e8d9d5df8f2c", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "726a27c2-c88c-48f0-9bf1-a7e1bfe6315c", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "3fc18d76-359d-4b4e-87ed-691ef36b6088", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-address-mapper", "saml-role-list-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper", "oidc-usermodel-attribute-mapper" ] + } + }, { + "id" : "0047597e-631e-4d3c-a1e8-19b181c9cf68", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper" ] + } + }, { + "id" : "b8aa76ca-61ef-4ab7-a516-08c31a7af62a", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "85ee92f9-7919-4230-a7ec-614a14adeef5", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "7fc80f56-c5cf-485e-81ff-ed59c75a0741", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + } ], + "org.keycloak.keys.KeyProvider" : [ { + "id" : "dfbc7b81-1627-4609-9ff6-8c5560c6fc21", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEogIBAAKCAQEAyz8jJRO3G8RyX5OcRUoRnVf0fx8hw1bhh/aA77alGCdtV0lhgSyGpC6wAjQPHKJxpX2qAMeJuPx37WVMmhR+HR65sOCYPbXj2hUTFqEkfsEEGWq8Yxk3nR2+eMpOT4QZtEAvX5609kyW/O6QgtcbCsYlKlEJk46ttjFqNWkgGpvnWluIqoQRGJoxTx/q3Vfr3eHf16WJJBp8nIWebyY+Bpo0fdQRrFIpjDPq+6XpeEEaRJEKey3L4fGPPABycx+D/XYKK0cFK3vKjz4wxs2tqXUuos7V2ojhTHUiq4pGewXdqh3wA/KanFzt6RwNeT0Inx786Z3F+Cfw9iCXLT9wYQIDAQABAoIBAFHjD8Fd9p3Q4bXhTopaI8uthrv66or9w6MYbW1nPJAFPpf24Dp/moWmq9JPcDE8v6YKAccLndDyo0z5zcmcbQ1FdlItwxjF4lXYvNaWuRH6qTCmYN1aaR47wCSBediuo/6MB6oyUr2TMRgZ9A5LJUGLgKjSepXBW/q2YRDA2KbvJbh3m6fDvN0cYk85N25LkQCZHS19eTFhhOrbgKspWhPh9KZ5KA9dDnYB/TsOFaYNnxZMMdeJ5OWBBTOV0VrUul+HYQMUSfnzq+z79o8MLIkp5k0fs4MIDeF7kfz4JbpIv7rloJIAOYnRvC1cs9Oxgh3I24Ysdk+WBIkk/n7HyVsCgYEA+yL69xIce6L3vDyoqMsckfe0k+Upg7L2eTArvYIcNieMd4sHLr6FAVtREUQz1xAPjpkcX9vbhgygN715anLJog+c4FbSUQNMhV64AnqHwajpFPcGCwHsn0hsp0sHB9GZbm6M64nNa1gOKT/XXlVMSb4WMMwumFVgJ7nTQF6YLXMCgYEAzy69h/WckUcG3N++mrwagCQFsYdks8ZdhKw3BNN7bMNqtgRYjBK+iIchnZmwByFIwnkrEWete2uXU09IMQ89wPZoJQpzdlKf3PkbVonK4fWY1xuMDgNWReh3CHe8isy/qe+4rS8hNYyI/5GqjQ65S4upmdH5zBYBje/686fJddsCgYANItNFwSjEPs3+hp271oP0DqTfZ4k4XlAOHrrq+rdHDeKHDjqd81E5tPEUmiCsCycFKnUVfoaJCHgI8lw7eS2a0H5ALcpqemWyRDYTyxz2wEMQ2arzQHKEEmG8jmwbuJbx885jM54PE1gKSFCXmpaW9N5sRwHY7f5Nlaa7IzeKiQKBgAMmDrNWRD7g+XW54MexPCXeZkfAawNgbGNryppELIgGoESL5FycnFCu3Q/sGgTBuL1b4g+tp7FMfUxC1DIKrUGVfRezBPYzY0KUdpnmFjNA7EW4oXRFELaXRdfXGgJyAievAPuAz9xkemCH8jOama5QPQ+dZVJ4syVZFFNHpYQpAoGAHXRkywDBvxb/R0q+/tZh0yjzB1c9+eKBc0XBJnfytL5YPC8mzCY6FhqFApewpORQyQMP/6ZX24HSGe7FUjjpe+nbLu708oUw0d3h6PdLjda17+Rh0O/zuOOhKwYY14VzvAmBjrjN3pwZ6pkEmW7OdQCIChskXJmAlYVo89suJ2c=" ], + "keyUse" : [ "SIG" ], + "certificate" : [ "MIICrTCCAZUCBgGSQ0hD5jANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9yZXF1aXJlZC1hY3Rpb24wHhcNMjQwOTMwMTQxMjQyWhcNMzQwOTMwMTQxNDIyWjAaMRgwFgYDVQQDDA9yZXF1aXJlZC1hY3Rpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLPyMlE7cbxHJfk5xFShGdV/R/HyHDVuGH9oDvtqUYJ21XSWGBLIakLrACNA8conGlfaoAx4m4/HftZUyaFH4dHrmw4Jg9tePaFRMWoSR+wQQZarxjGTedHb54yk5PhBm0QC9fnrT2TJb87pCC1xsKxiUqUQmTjq22MWo1aSAam+daW4iqhBEYmjFPH+rdV+vd4d/XpYkkGnychZ5vJj4GmjR91BGsUimMM+r7pel4QRpEkQp7Lcvh8Y88AHJzH4P9dgorRwUre8qPPjDGza2pdS6iztXaiOFMdSKrikZ7Bd2qHfAD8pqcXO3pHA15PQifHvzpncX4J/D2IJctP3BhAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAZt5mCaF2sZF9wpERfTdXTGSgf0U03ihaEcfsTJrZuclcy3YyD+/20HnMzBpsQ9Yyn1H4juBfVXBjj7jFvKp6V53l80vsyGb27lJejhQUjyolgtF0oTAvxXxNGVoEmQw6a63Ah2gQqd0gOyXUd8SIfz4ZRW2Y/j/PHQD6uqU4Fb8xu9nGWh18WECj3/uoPH/DVnEcIZD3gJKkcC347lA8GnCiW0hkXBI4W5y6R+VAg3sDzn+5nkeW0L7hMvl43xruz9ffPMoZjeJm40OLiCAiLHN+W5IavDhdu5UDQWowDb8OLP8e4GQ6OSjVFTUE7p8tVufP5W6S91UOHeHSEe5lI=" ], + "priority" : [ "100" ] + } + }, { + "id" : "1eed8b04-a1cb-433c-a0d7-ef80f3f8fc61", + "name" : "aes-generated", + "providerId" : "aes-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "9a74fc2f-2a1a-4c13-8d48-861c9b99b883" ], + "secret" : [ "SUda6U6nGDMD6dimITVPbw" ], + "priority" : [ "100" ] + } + }, { + "id" : "a35d916b-1d3e-427d-aa4d-c00c0e66fef4", + "name" : "hmac-generated", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "c0fbc628-3d38-42f4-8eff-a57c9231d67a" ], + "secret" : [ "FzJnfnthnlhr3lUKM1V44CSAcbR4d8ff0z7yIjm6Bv8ijUedsKKV_aqaHX6PgMgdivXisfXRU3E5YS6wfO_CIw" ], + "priority" : [ "100" ], + "algorithm" : [ "HS256" ] + } + }, { + "id" : "22492d1a-7bbd-4812-9224-5aee3045294b", + "name" : "rsa-enc-generated", + "providerId" : "rsa-enc-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEpAIBAAKCAQEAuSCftU3gpJQD/Izq70TGFd9eJRlsGcJ5DL6sV/uIWf3i55uMh7ZaSVxnBzBXijsiTzdOqwMFXzHcSYPfqoXwBlILhD74iDwYgtkq3e48EnjSUvt+RRlkQDW6l+9cqKD81pcn6NqY1Yxz1wG8liHd9pUsTY43JjhdNzeWKByYJNCsHPAWvKUjZGLIbk5QlZC7SkLC49bv+BbQZBdiLDjNXo2drCIIuAfRFJmBePkGVJEV2+ps7ajgMJWkM1s8hMV/NdIIX0HdspBrv/4isDbsFmQS5htpgJvVrUWPdvzyogfOaHSRMLahy9+Vr+as9n6BCD2bX9MLg4fKgTNo9/L3SwIDAQABAoIBADoipRS17pAwTSovhI173uq6eOGUoK5cNFBMxmlgu3prMKjD37c0jBjSlCYdR7hIhqcyupkYe0TgLwnFCGWP5wbNGAHBFqINoTLiCMSlziaM25ukj4wag7FoTf7tc38fAxdOY4GLuAgDsdL4oCTTYNVRFhcKzIXLmHZBFf3lsN+KQG6QRW+negl60h5op2rYcAmB9yzJiEKCJa8v7zRa4fhBn4C2ndmrJeXHj2+avVZMUGejf2VEnVXqh1l7mJ1+qoD4Kn/hiWVj3ZKANmOkkIbLBw3wwpBbtIkfxlFW7RsTedBL7Vo3dDH3Lytl/e/tJV48544XGKEcXZdP9qbuS6UCgYEA9buEt0B1RIx3Iwxzvb7dbIW7U7+HuUXMu/xZEfRp36RWiwMlNlle/5AJwDBVTDF06gd5tIrhXKjZLGRrs68rl09gGc4om/lTRFKFmB22oB4Bd6B9xAKZ8HsrkBXhOnn1jEb0yeZc4mlbNCjoIek7Zi2HwmydpwGteyiK1mcWKk0CgYEAwNzXrDwCX2NgHFun4xHpYzShAApFqPKhjE5ygv1/5l43JoiLmGgpr2rVAzCEqvFHFt1URAW1/5osJESlbzWAh8hb+9as71D/RUn8NYQ3MN4WqygppAKwwEXVBJ71PXiWctHcpvDt5yWfqgVCmuALpGMbOkD8zIAmESFyjol2Q/cCgYEAtykTbkgEYJjWgHBaoPbwMmCn1W+wqZ9mUERy25gzhjgHLcylYxJQZesl6XPdUFKY04vI4pKWEivk3FrpkGAj/L90YSeySzgXIZjk7RJQup5C97jPpVdPCNm2CcrVO3IGXY3SDd/AIh7nlURcalJfLPUI+RlelUoB1gfNHKxv8A0CgYAcnOcWc3S6qCirLGH1C0Q/5p/4PI3nKdAT29ObYXanO9Ucz2c+fj2o+8WMipc0MUWlu8JzsRE2Ua4410JgBGUEQBJ9g3T2sGKe6gIUAoCZrGlajUPYRFnqvLGE1Px3WTug30fIMLhq8acFd3BRP+oaQmXYt6mJwX1kTz0KrpQwMwKBgQDVxOgQehMs2srTEW8FeI09ATsRPu7WQsIQYuo3s8hghELY0/2XUtaLQVq16aWgn4ajl7OsmFQc5kxvE5uuCee2x4lc0nQzw5d9Sn2qkJlavwC3n/WA0f8dBYV0Id7He73XL5WMyUVuwWpwiT37QYrmtLpAnQwa6iH+jHmjEyTTaA==" ], + "keyUse" : [ "ENC" ], + "certificate" : [ "MIICrTCCAZUCBgGSQ0hELDANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9yZXF1aXJlZC1hY3Rpb24wHhcNMjQwOTMwMTQxMjQyWhcNMzQwOTMwMTQxNDIyWjAaMRgwFgYDVQQDDA9yZXF1aXJlZC1hY3Rpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5IJ+1TeCklAP8jOrvRMYV314lGWwZwnkMvqxX+4hZ/eLnm4yHtlpJXGcHMFeKOyJPN06rAwVfMdxJg9+qhfAGUguEPviIPBiC2Srd7jwSeNJS+35FGWRANbqX71yooPzWlyfo2pjVjHPXAbyWId32lSxNjjcmOF03N5YoHJgk0Kwc8Ba8pSNkYshuTlCVkLtKQsLj1u/4FtBkF2IsOM1ejZ2sIgi4B9EUmYF4+QZUkRXb6mztqOAwlaQzWzyExX810ghfQd2ykGu//iKwNuwWZBLmG2mAm9WtRY92/PKiB85odJEwtqHL35Wv5qz2foEIPZtf0wuDh8qBM2j38vdLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJ6UEBe3gqGQ5juBVVyovv5Uao0HfdTOWqHBPuUPXopTqeeAW6eVmfFh10e8JltnlfafT1mPfd3nDYD7JPdlKMMlZdL92DoYTx45vtld59Nk72fwf5lmZ2xc6T4kJG8MPH0mNf5oroTTZ71SE/pfEbhAMBE3I3e3977n5HJu+00Ir4DB1xaEV5155BW8SY0Azx/ekaO2bWf1cbropul9ZAxvq0QJQjKPwVXFAWf1r9M0MMCEMeqJKYh2rV/im/JJm/76XuxahKgy2yKrwXkwUKeaa+lxhnEWsvHMtMUa6AJBuFi4MmWtvbxcC5xHresKERhu0aToXszNHBYtwoBlCjc=" ], + "priority" : [ "100" ], + "algorithm" : [ "RSA-OAEP" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "6b68fc0a-9a5b-4802-8905-5be8f1f802b3", + "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" : "392e1ee1-ea41-4032-80b0-43116e0def51", + "alias" : "AuthN", + "description" : "", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : false, + "authenticationExecutions" : [ { + "authenticator" : "auth-username-password-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 0, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorConfig" : "Req", + "authenticator" : "required-action-authenticator", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 1, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "05267f8b-ada8-4f80-a05e-9785b4d22e1a", + "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" : "d8efa2e8-72b0-45a2-a17c-5750536a7e89", + "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" : "d7b1fee5-e630-4535-a5ae-296ab22c5756", + "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" : "dcd597cc-452a-408e-9ed7-6eb90f7f97b7", + "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" : "13e2ebf0-0898-4f9e-8463-69beb652ee62", + "alias" : "Required-Action-Browser FLOW", + "description" : "", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : false, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 0, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 1, + "autheticatorFlow" : true, + "flowAlias" : "AuthN", + "userSetupAllowed" : false + } ] + }, { + "id" : "c827ab09-f810-465b-b982-bf936fb46c3a", + "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" : "be5a6343-d99e-4657-bf92-f02fb6c4c280", + "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" : "be8d8810-2f64-4665-b68c-6b6aaf6773ab", + "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" : "40646673-4496-4aa4-866b-0a8be6f0a37d", + "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" : "8d59560c-9cab-43b1-a4e9-177785fe3935", + "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" : "1f374eeb-8749-4ad4-bfc9-dd1c9d2f49f6", + "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" : "9bce60a9-3584-478d-bcc0-41b926a4caad", + "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" : "ecfeb6fc-71b6-40fb-a9ad-7ea6843bba4f", + "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" : "c0f5845e-e01e-4ed8-a213-59546894877b", + "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" : "bb4e2b10-64fc-4d36-be54-fd2feadbe5fe", + "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" : "2c12bf9a-94f8-4da6-848f-9623170a5bb2", + "alias" : "registration form", + "description" : "registration form", + "providerId" : "form-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-user-creation", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-password-action", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 50, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-recaptcha-action", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 60, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "a8886f6f-a820-4764-8b22-7ef44213235c", + "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" : "30ffba64-fe30-411b-9229-392e311b28f9", + "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" : "9b46ecb5-2b16-40f0-beae-4fc4ba905292", + "alias" : "Req", + "config" : { + "REQUIRED_ACTION" : "TERMS_AND_CONDITIONS" + } + }, { + "id" : "4514cd86-3494-44ff-9f8a-60ecf7c71c0b", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "6a0a4b1c-ac61-4e82-a00a-6a65a9736f71", + "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" : true, + "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" : "Required-Action-Browser FLOW", + "registrationFlow" : "registration", + "directGrantFlow" : "direct grant", + "resetCredentialsFlow" : "reset credentials", + "clientAuthenticationFlow" : "clients", + "dockerAuthenticationFlow" : "docker auth", + "attributes" : { + "cibaBackchannelTokenDeliveryMode" : "poll", + "cibaExpiresIn" : "120", + "cibaAuthRequestedUserHint" : "login_hint", + "oauth2DeviceCodeLifespan" : "600", + "clientOfflineSessionMaxLifespan" : "0", + "oauth2DevicePollingInterval" : "5", + "clientSessionIdleTimeout" : "0", + "parRequestUriLifespan" : "60", + "clientSessionMaxLifespan" : "0", + "clientOfflineSessionIdleTimeout" : "0", + "cibaInterval" : "5", + "realmReusableOtpCode" : "false" + }, + "keycloakVersion" : "23.0.4", + "userManagedAccessAllowed" : false, + "clientProfiles" : { + "profiles" : [ ] + }, + "clientPolicies" : { + "policies" : [ ] + }, + "users" : [ { + "createdTimestamp" : 1714724986126, + "username" : "dieterbohlen", + "enabled" : true, + "totp" : false, + "emailVerified" : true, + "firstName" : "Dieter", + "lastName" : "Bohlen", + "email" : "dieterbohlen@test.de", + "attributes" : { + "someKey" : [ "someValue" ] + }, + "credentials" : [ { + "type" : "password", + "userLabel" : "My password", + "createdDate" : 1714984887328, + "secretData" : "{\"value\":\"fkI60a2oucKmbh+4rCJFJmT6KCGhgJpnRprkKwbs19U=\",\"salt\":\"9Qyws0F21aRbjv81y4ko6Q==\",\"additionalParameters\":{}}", + "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}" + } ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "default-roles-required-action" ], + "notBefore" : 0, + "groups" : [ ] + }, { + "createdTimestamp" : 1714725047521, + "username" : "mannimammut", + "enabled" : true, + "totp" : false, + "emailVerified" : true, + "firstName" : "Manni", + "lastName" : "Mammut", + "email" : "mannimammut@test.de", + "credentials" : [ { + "type" : "password", + "userLabel" : "My password", + "createdDate" : 1727706889214, + "secretData" : "{\"value\":\"AvC4u0736U6fV2pinQSf1IUJWYPfIZml6V6IuAWcXqo=\",\"salt\":\"QUFh9poULtQHwS31z9n9+Q==\",\"additionalParameters\":{}}", + "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}" + } ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "default-roles-required-action" ], + "notBefore" : 0, + "groups" : [ ] + }, { + "createdTimestamp" : 1714725026271, + "username" : "peterpommes", + "enabled" : true, + "totp" : false, + "emailVerified" : true, + "firstName" : "Peter", + "lastName" : "Pommes", + "email" : "peterpommes@test.de", + "credentials" : [ { + "id" : "4802a77d-e2f5-429d-a753-180530820e17", + "type" : "password", + "userLabel" : "My password", + "createdDate" : 1727706906795, + "secretData" : "{\"value\":\"Oy8FtfOWnOE3m8nAAApef0Bv1b1uvKcfUbAoc/9bqes=\",\"salt\":\"4cMW+tH6XxwjR6O2zbPfMQ==\",\"additionalParameters\":{}}", + "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}" + } ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "default-roles-required-action" ], + "notBefore" : 0, + "groups" : [ ] + } ] +} diff --git a/docker-compose.yaml b/docker-compose.yaml index a139322..376f674 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,5 +1,3 @@ -version: '3' - services: keycloak: image: quay.io/keycloak/keycloak:23.0.4 @@ -18,6 +16,8 @@ services: volumes: - "./keycloak-extension-rest/target/keycloak-extension-rest-1.0-SNAPSHOT.jar:/opt/keycloak/providers/keycloak-extension-rest.jar" - "./keycloak-extension-rest/src/test/resources/conciso-realm.json:/opt/keycloak/data/import/conciso-realm.json" + - "./authenticator-required-action/target/authenticator-required-action-1.0-SNAPSHOT.jar:/opt/keycloak/providers/authenticator-required-action.jar" + - "./authenticator-required-action/src/test/resources/required-action-realm.json:/opt/keycloak/data/import/required-action-realm.json" depends_on: postgres: condition: service_healthy diff --git a/docs/pics/required-action-authenticator-config.png b/docs/pics/required-action-authenticator-config.png new file mode 100644 index 0000000..f4025a7 Binary files /dev/null and b/docs/pics/required-action-authenticator-config.png differ diff --git a/docs/pics/required-action-available-required-actions.png b/docs/pics/required-action-available-required-actions.png new file mode 100644 index 0000000..d1750c5 Binary files /dev/null and b/docs/pics/required-action-available-required-actions.png differ diff --git a/docs/pics/required-action-flow.png b/docs/pics/required-action-flow.png new file mode 100644 index 0000000..6fc6087 Binary files /dev/null and b/docs/pics/required-action-flow.png differ diff --git a/pom.xml b/pom.xml index b716103..eb02b3c 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,7 @@ keycloak-extensions + authenticator-required-action keycloak-extension-rest user-management @@ -53,6 +54,7 @@ 5.5.0 5.11.3 2.24.1 + 1.47.0 @@ -100,7 +102,13 @@ ${version.keycloak} provided - + + + com.microsoft.playwright + playwright + ${version.playwright} + test +