keycloak-aplcache

Details

diff --git a/server-spi/src/main/java/org/keycloak/policy/PasswordPolicyNotMetException.java b/server-spi/src/main/java/org/keycloak/policy/PasswordPolicyNotMetException.java
new file mode 100644
index 0000000..24643bb
--- /dev/null
+++ b/server-spi/src/main/java/org/keycloak/policy/PasswordPolicyNotMetException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.policy;
+
+import org.keycloak.models.ModelException;
+
+/**
+ * @author <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
+ */
+public class PasswordPolicyNotMetException extends ModelException {
+
+    private String username;
+
+    public PasswordPolicyNotMetException() {
+        super();
+    }
+
+    public PasswordPolicyNotMetException(String message) {
+        super(message);
+    }
+
+    public PasswordPolicyNotMetException(String message, String username) {
+        super(message);
+        this.username = username;
+    }
+    
+    public PasswordPolicyNotMetException(String message, String username, Throwable cause) {
+        super(message, cause);
+        this.username = username;
+    }
+
+    public PasswordPolicyNotMetException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public PasswordPolicyNotMetException(Throwable cause) {
+        super(cause);
+    }
+
+    public String getUsername() {
+        return username;
+    }
+}
diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index 5fb5003..98ccf38 100755
--- a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -79,6 +79,7 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserProvider;
 import org.keycloak.models.credential.PasswordUserCredentialModel;
+import org.keycloak.policy.PasswordPolicyNotMetException;
 import org.keycloak.provider.ProviderConfigProperty;
 import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
@@ -1534,7 +1535,17 @@ public class RepresentationToModel {
         if (cred.getValue() != null) {
             PasswordUserCredentialModel plainTextCred = convertCredential(cred);
             plainTextCred.setAdminRequest(adminRequest);
-            session.userCredentialManager().updateCredential(realm, user, plainTextCred);
+            
+            //if called from import we need to change realm in context to load password policies from the newly created realm
+            RealmModel origRealm = session.getContext().getRealm();
+            try {
+                session.getContext().setRealm(realm);
+                session.userCredentialManager().updateCredential(realm, user, plainTextCred);
+            } catch (ModelException ex) {
+                throw new PasswordPolicyNotMetException(ex.getMessage(), user.getUsername(), ex);
+            } finally {
+                session.getContext().setRealm(origRealm);
+            }
         } else {
             CredentialModel hashedCred = new CredentialModel();
             hashedCred.setType(cred.getType());
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
index 7fd223f..76fb999 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
@@ -21,6 +21,7 @@ import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.common.ClientConnection;
+import org.keycloak.policy.PasswordPolicyNotMetException;
 import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
@@ -148,6 +149,10 @@ public class RealmsAdminResource {
         } catch (ModelDuplicateException e) {
             logger.error("Conflict detected", e);
             return ErrorResponse.exists("Conflict detected. See logs for details");
+        } catch (PasswordPolicyNotMetException e) {
+            logger.error("Password policy not met for user " + e.getUsername(), e);
+            if (session.getTransactionManager().isActive()) session.getTransactionManager().setRollbackOnly();
+            return ErrorResponse.error("Password policy not met. See logs for details", Response.Status.BAD_REQUEST);
         }
     }
 
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/updaters/RealmRemover.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/updaters/RealmRemover.java
new file mode 100644
index 0000000..3b42cb0
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/updaters/RealmRemover.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.updaters;
+
+import java.io.Closeable;
+import javax.ws.rs.NotFoundException;
+import org.keycloak.admin.client.resource.RealmResource;
+
+/**
+ *
+ * @author <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
+ */
+public class RealmRemover {
+
+    private final RealmResource realmResource;
+
+    public RealmRemover(RealmResource realmResource) {
+        this.realmResource = realmResource;
+    }
+
+    public Closeable remove() {
+        return () -> {
+            try {
+                realmResource.remove();
+            } catch (NotFoundException e) {
+            }
+        };
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java
index dbd8c43..06cafa4 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java
@@ -23,8 +23,10 @@ import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.admin.client.Keycloak;
+import org.keycloak.admin.client.resource.RealmResource;
 import org.keycloak.admin.client.resource.ServerInfoResource;
 import org.keycloak.common.util.Time;
 import org.keycloak.events.admin.OperationType;
@@ -50,6 +52,7 @@ import org.keycloak.testsuite.auth.page.AuthRealm;
 import org.keycloak.testsuite.client.KeycloakTestingClient;
 import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
 import org.keycloak.testsuite.runonserver.RunHelpers;
+import org.keycloak.testsuite.updaters.RealmRemover;
 import org.keycloak.testsuite.util.AdminEventPaths;
 import org.keycloak.testsuite.util.ClientBuilder;
 import org.keycloak.testsuite.util.CredentialBuilder;
@@ -60,6 +63,7 @@ import org.keycloak.util.JsonSerialization;
 
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.core.Response;
+import java.io.Closeable;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
@@ -68,6 +72,7 @@ import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import javax.ws.rs.BadRequestException;
 
 import static org.junit.Assert.*;
 
@@ -83,6 +88,8 @@ public class RealmTest extends AbstractAdminTest {
 
     @Rule
     public AssertEvents events = new AssertEvents(this);
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
 
     @Test
     public void getRealms() {
@@ -195,6 +202,40 @@ public class RealmTest extends AbstractAdminTest {
         adminClient.realms().realm("admin-test-1").remove();
     }
 
+    //KEYCLOAK-6146
+    @Test
+    public void createRealmWithPasswordPolicyFromJsonWithInvalidPasswords() {
+        //try to create realm with password policies and users with plain-text passwords what doesn't met the policies
+        RealmRepresentation rep = loadJson(getClass().getResourceAsStream("/import/testrealm-keycloak-6146-error.json"), RealmRepresentation.class);
+
+        expectedException.expect(NotFoundException.class);
+        expectedException.expectMessage(String.valueOf(Response.Status.NOT_FOUND.getStatusCode()));
+
+        try {
+            adminClient.realms().create(rep);
+        } catch (BadRequestException ex) {
+            //ensure the realm was not created
+            log.info("--Caught expected BadRequestException--");
+            adminClient.realms().realm("secure-app").toRepresentation();
+        }
+        //test will fail on AssertionError when both BadRequestException and NotFoundException is not thrown
+    }
+    
+    //KEYCLOAK-6146
+    @Test
+    public void createRealmWithPasswordPolicyFromJsonWithValidPasswords() throws IOException {
+        //realm with password policies and users have passwords in correct state
+        RealmRepresentation rep = loadJson(getClass().getResourceAsStream("/import/testrealm-keycloak-6146.json"), RealmRepresentation.class);
+        adminClient.realms().create(rep);
+        
+        RealmResource secureApp = adminClient.realms().realm("secure-app");
+        RealmRepresentation created = secureApp.toRepresentation();
+        
+        try (Closeable c = new RealmRemover(secureApp).remove()) {
+            assertRealm(rep, created);
+        }
+    }
+
     @Test
     public void removeRealm() {
         realm.remove();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/import/testrealm-keycloak-6146.json b/testsuite/integration-arquillian/tests/base/src/test/resources/import/testrealm-keycloak-6146.json
new file mode 100644
index 0000000..a5720f2
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/import/testrealm-keycloak-6146.json
@@ -0,0 +1,606 @@
+{
+   "id":"secure-app",
+   "realm":"secure-app",
+   "accessCodeLifespanUserAction" : 300,
+   "enabled":true,
+   "sslRequired":"external",
+   "bruteForceProtected" : true,
+   "permanentLockout": true,
+   "maxFailureWaitSeconds" : 900,
+   "minimumQuickLoginWaitSeconds" : 60,
+   "waitIncrementSeconds" : 60,
+   "quickLoginCheckMilliSeconds" : 1000,
+   "maxDeltaTimeSeconds" : 43200,
+   "failureFactor" : 3,
+   "eventsEnabled" : true,
+   "eventsListeners" : [ "jboss-logging" ],
+   "enabledEventTypes" : [ "SEND_RESET_PASSWORD", "UPDATE_TOTP", "REMOVE_TOTP", "REVOKE_GRANT", "LOGIN_ERROR", "CLIENT_LOGIN", "RESET_PASSWORD_ERROR", "IMPERSONATE_ERROR", "CODE_TO_TOKEN_ERROR", "CUSTOM_REQUIRED_ACTION", "RESTART_AUTHENTICATION", "UPDATE_PROFILE_ERROR", "IMPERSONATE", "LOGIN", "UPDATE_PASSWORD_ERROR", "CLIENT_INITIATED_ACCOUNT_LINKING", "REGISTER", "LOGOUT", "CLIENT_REGISTER", "IDENTITY_PROVIDER_LINK_ACCOUNT", "UPDATE_PASSWORD", "FEDERATED_IDENTITY_LINK_ERROR", "CLIENT_DELETE", "IDENTITY_PROVIDER_FIRST_LOGIN", "VERIFY_EMAIL", "CLIENT_DELETE_ERROR", "CLIENT_LOGIN_ERROR", "RESTART_AUTHENTICATION_ERROR", "REMOVE_FEDERATED_IDENTITY_ERROR", "EXECUTE_ACTIONS", "SEND_IDENTITY_PROVIDER_LINK_ERROR", "EXECUTE_ACTION_TOKEN_ERROR", "SEND_VERIFY_EMAIL", "EXECUTE_ACTIONS_ERROR", "REMOVE_FEDERATED_IDENTITY", "IDENTITY_PROVIDER_POST_LOGIN", "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", "UPDATE_EMAIL", "REGISTER_ERROR", "REVOKE_GRANT_ERROR", "LOGOUT_ERROR", "UPDATE_EMAIL_ERROR", "EXECUTE_ACTION_TOKEN", "CLIENT_UPDATE_ERROR", "UPDATE_PROFILE", "FEDERATED_IDENTITY_LINK", "CLIENT_REGISTER_ERROR", "SEND_VERIFY_EMAIL_ERROR", "SEND_IDENTITY_PROVIDER_LINK", "RESET_PASSWORD", "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", "REMOVE_TOTP_ERROR", "VERIFY_EMAIL_ERROR", "SEND_RESET_PASSWORD_ERROR", "CLIENT_UPDATE", "IDENTITY_PROVIDER_POST_LOGIN_ERROR", "CUSTOM_REQUIRED_ACTION_ERROR", "UPDATE_TOTP_ERROR", "CODE_TO_TOKEN", "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" ],
+   "adminEventsEnabled" : true,
+   "adminEventsDetailsEnabled" : true,
+   "requiredCredentials":[
+      "password"
+   ],
+   "passwordPolicy": "length(10) and lowerCase(1) and upperCase(1) and passwordHistory(3) and digits(1) and specialChars(1) and hashAlgorithm(pbkdf2-sha256)",
+   "users":[
+      {
+         "username":"user1",
+         "firstName" : "User",
+         "lastName" : "1",
+         "email" : "user1@feedhenry.org",
+         "enabled":true,
+         "credentials":[
+            {
+               "type":"password",
+               "value":"Password123!"
+            }
+         ],
+         "clientRoles":{
+            "account":[
+               "view-profile",
+               "manage-account"
+            ]
+         },
+         "attributes":{
+
+         },
+        "groups" : [ "/Mobile Users" ]
+      },
+      {
+         "username":"user2",
+         "firstName" : "User",
+         "lastName" : "2",
+         "email" : "user2@feedhenry.org",
+         "enabled":true,
+         "credentials":[
+            {
+               "type":"password",
+               "value":"Password123!"
+            }
+         ],
+         "clientRoles":{
+            "account":[
+               "view-profile",
+               "manage-account"
+            ]
+         },
+         "attributes":{
+
+         },
+         "groups" : [ "/Mobile Users" ]
+      },
+      {
+         "username":"secure-user",
+         "enabled" : true,
+          "emailVerified" : true,
+          "firstName" : "Secure",
+          "lastName" : "User",
+          "email" : "secure-user@feedhenry.org",
+         "credentials":[
+            {
+               "type":"password",
+               "value":"Password123!"
+            }
+         ],
+         "requiredActions" : [ "CONFIGURE_TOTP" ],
+         "realmRoles" : [ ],
+         "clientRoles":{
+            "account":[
+               "view-profile",
+               "manage-account"
+            ]
+         },
+         "attributes":{
+
+         },
+         "groups" : [ "/Mobile Users", "/API Access" ]
+      },
+      {
+         "username":"secure-user2",
+         "enabled" : true,
+          "emailVerified" : true,
+          "firstName" : "Secure",
+          "lastName" : "User 2",
+          "email" : "secure-user2@feedhenry.org",
+         "credentials":[
+            {
+               "type":"password",
+               "value":"Password123!"
+            }
+         ],
+         "requiredActions" : [ "CONFIGURE_TOTP" ],
+         "realmRoles" : [ ],
+         "clientRoles":{
+            "account":[
+               "view-profile",
+               "manage-account"
+            ]
+         },
+         "attributes":{
+
+         },
+         "groups" : [ "/Mobile Users", "/API Access" ]
+      },
+      {
+         "username":"superuser",
+         "enabled" : true,
+          "emailVerified" : true,
+          "firstName" : "Super",
+          "lastName" : "User",
+          "email" : "superuser@feedhenry.org",
+         "credentials":[
+            {
+               "type":"password",
+               "value":"Password123!"
+            }
+         ],
+         "realmRoles" : [ ],
+         "clientRoles":{
+            "account":[
+               "view-profile",
+               "manage-account"
+            ]
+         },
+         "attributes":{
+
+         },
+         "groups" : [ "/Mobile Users", "/API Access", "Superuser" ]
+      }
+   ],
+   "clients":[
+      {
+         "clientId":"api-server",
+         "enabled":true,
+         "bearerOnly":true,
+         "adminUrl":"http://localhost:8080"
+      },
+      {
+         "clientId":"client-app",
+         "enabled":true,
+         "publicClient":true,
+         "redirectUris":[
+            "com.feedhenry.securenativeandroidtemplate:/callback"
+         ],
+         "webOrigins":[
+            "*"
+         ]
+      }
+   ],
+   "clientScopeMappings":{
+      "account":[
+         {
+            "client":"api-server",
+            "roles":[
+               "view-profile"
+            ]
+         },
+         {
+            "client":"client-app",
+            "roles":[
+               "view-profile"
+            ]
+         }
+      ]
+   },
+   "groups" : [ {
+     "name" : "Mobile Users",
+     "path" : "/Mobile Users",
+     "attributes" : { },
+     "realmRoles" : [ "mobile-user" ],
+     "clientRoles" : { },
+     "subGroups" : [ ]
+   },
+   {
+     "name" : "API Access",
+     "path" : "/API Access",
+     "attributes" : { },
+     "realmRoles" : [ "mobile-user", "api-access" ],
+     "clientRoles" : { },
+     "subGroups" : [ ]
+   },
+   {
+     "name" : "Superuser",
+     "path" : "/Superusers",
+     "attributes" : { },
+     "realmRoles" : [ "mobile-user", "api-access", "superuser" ],
+     "clientRoles" : { },
+     "subGroups" : [ ]
+   } ],
+   "roles":{
+      "client":{
+         "api-server":[
+
+         ],
+         "client-app":[
+
+         ]
+      }
+   },
+   "authenticationFlows" : [ {
+    "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",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "idp-email-verification",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "requirement" : "ALTERNATIVE",
+      "priority" : 30,
+      "flowAlias" : "Verify Existing Account by Re-authentication",
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : true
+    } ]
+  }, {
+    "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",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "auth-otp-form",
+      "requirement" : "OPTIONAL",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "X.509 Browser",
+    "description" : "browser based authentication",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : false,
+    "authenticationExecutions" : [ {
+      "authenticator" : "auth-cookie",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "auth-spnego",
+      "requirement" : "DISABLED",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticatorConfig" : "authenticator config",
+      "authenticator" : "identity-provider-redirector",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 25,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticatorConfig" : "x509 browser auth config",
+      "authenticator" : "auth-x509-client-username-form",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 30,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "requirement" : "ALTERNATIVE",
+      "priority" : 31,
+      "flowAlias" : "X.509 Browser forms",
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : true
+    } ]
+  }, {
+    "alias" : "X.509 Browser forms",
+    "description" : "Username, password, otp and other auth forms.",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : false,
+    "authenticationExecutions" : [ {
+      "authenticator" : "auth-username-password-form",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "auth-otp-form",
+      "requirement" : "OPTIONAL",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "X.509 Direct Grant",
+    "description" : "OpenID Connect Resource Owner Grant",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : false,
+    "authenticationExecutions" : [ {
+      "authenticatorConfig" : "x509 direct grant config",
+      "authenticator" : "direct-grant-auth-x509-username",
+      "requirement" : "REQUIRED",
+      "priority" : 0,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "browser",
+    "description" : "browser based authentication",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "auth-cookie",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "auth-spnego",
+      "requirement" : "DISABLED",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "identity-provider-redirector",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 25,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "requirement" : "ALTERNATIVE",
+      "priority" : 30,
+      "flowAlias" : "forms",
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : true
+    } ]
+  }, {
+    "alias" : "clients",
+    "description" : "Base authentication for clients",
+    "providerId" : "client-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "client-secret",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "client-jwt",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "direct grant",
+    "description" : "OpenID Connect Resource Owner Grant",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "direct-grant-validate-username",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "direct-grant-validate-password",
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "direct-grant-validate-otp",
+      "requirement" : "OPTIONAL",
+      "priority" : 30,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "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",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "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",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticatorConfig" : "create unique user config",
+      "authenticator" : "idp-create-user-if-unique",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "requirement" : "ALTERNATIVE",
+      "priority" : 30,
+      "flowAlias" : "Handle Existing Account",
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : true
+    } ]
+  }, {
+    "alias" : "forms",
+    "description" : "Username, password, otp and other auth forms.",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "auth-username-password-form",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "auth-otp-form",
+      "requirement" : "OPTIONAL",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "registration",
+    "description" : "registration flow",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "registration-page-form",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "flowAlias" : "registration form",
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : true
+    } ]
+  }, {
+    "alias" : "registration form",
+    "description" : "registration form",
+    "providerId" : "form-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "registration-user-creation",
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "registration-profile-action",
+      "requirement" : "REQUIRED",
+      "priority" : 40,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "registration-password-action",
+      "requirement" : "REQUIRED",
+      "priority" : 50,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "registration-recaptcha-action",
+      "requirement" : "DISABLED",
+      "priority" : 60,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "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",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "reset-credential-email",
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "reset-password",
+      "requirement" : "REQUIRED",
+      "priority" : 30,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "reset-otp",
+      "requirement" : "OPTIONAL",
+      "priority" : 40,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "saml ecp",
+    "description" : "SAML ECP Profile Authentication Flow",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "http-basic-authenticator",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  } ],
+  "authenticatorConfig" : [ {
+    "alias" : "authenticator config",
+    "config" : {
+      "defaultProvider" : ""
+    }
+  }, {
+    "alias" : "create unique user config",
+    "config" : {
+      "require.password.update.after.registration" : "false"
+    }
+  }, {
+    "alias" : "review profile config",
+    "config" : {
+      "update.profile.on.first.login" : "missing"
+    }
+  }, {
+    "alias" : "x509 browser auth config",
+    "config" : {
+      "x509-cert-auth.extendedkeyusage" : "",
+      "x509-cert-auth.mapper-selection.user-attribute-name" : "usercertificate",
+      "x509-cert-auth.ocsp-responder-uri" : "",
+      "x509-cert-auth.regular-expression" : "(.*?)(?:$)",
+      "x509-cert-auth.crl-checking-enabled" : "",
+      "x509-cert-auth.confirmation-page-disallowed" : "",
+      "x509-cert-auth.keyusage" : "",
+      "x509-cert-auth.mapper-selection" : "Username or Email",
+      "x509-cert-auth.crl-relative-path" : "crl.pem",
+      "x509-cert-auth.crldp-checking-enabled" : "false",
+      "x509-cert-auth.mapping-source-selection" : "Subject's Common Name",
+      "x509-cert-auth.ocsp-checking-enabled" : ""
+    }
+  }, {
+    "alias" : "x509 direct grant config",
+    "config" : {
+      "x509-cert-auth.extendedkeyusage" : "",
+      "x509-cert-auth.mapper-selection.user-attribute-name" : "usercertificate",
+      "x509-cert-auth.ocsp-responder-uri" : "",
+      "x509-cert-auth.regular-expression" : "(.*?)(?:$)",
+      "x509-cert-auth.crl-checking-enabled" : "",
+      "x509-cert-auth.confirmation-page-disallowed" : "",
+      "x509-cert-auth.keyusage" : "",
+      "x509-cert-auth.mapper-selection" : "Username or Email",
+      "x509-cert-auth.crl-relative-path" : "crl.pem",
+      "x509-cert-auth.crldp-checking-enabled" : "false",
+      "x509-cert-auth.mapping-source-selection" : "Subject's Common Name",
+      "x509-cert-auth.ocsp-checking-enabled" : ""
+    }
+  } ]
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/import/testrealm-keycloak-6146-error.json b/testsuite/integration-arquillian/tests/base/src/test/resources/import/testrealm-keycloak-6146-error.json
new file mode 100644
index 0000000..fa082d1
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/import/testrealm-keycloak-6146-error.json
@@ -0,0 +1,605 @@
+{
+   "id":"secure-app",
+   "realm":"secure-app",
+   "enabled":true,
+   "sslRequired":"external",
+   "bruteForceProtected" : true,
+   "permanentLockout": true,
+   "maxFailureWaitSeconds" : 900,
+   "minimumQuickLoginWaitSeconds" : 60,
+   "waitIncrementSeconds" : 60,
+   "quickLoginCheckMilliSeconds" : 1000,
+   "maxDeltaTimeSeconds" : 43200,
+   "failureFactor" : 3,
+   "eventsEnabled" : true,
+   "eventsListeners" : [ "jboss-logging" ],
+   "enabledEventTypes" : [ "SEND_RESET_PASSWORD", "UPDATE_TOTP", "REMOVE_TOTP", "REVOKE_GRANT", "LOGIN_ERROR", "CLIENT_LOGIN", "RESET_PASSWORD_ERROR", "IMPERSONATE_ERROR", "CODE_TO_TOKEN_ERROR", "CUSTOM_REQUIRED_ACTION", "RESTART_AUTHENTICATION", "UPDATE_PROFILE_ERROR", "IMPERSONATE", "LOGIN", "UPDATE_PASSWORD_ERROR", "CLIENT_INITIATED_ACCOUNT_LINKING", "REGISTER", "LOGOUT", "CLIENT_REGISTER", "IDENTITY_PROVIDER_LINK_ACCOUNT", "UPDATE_PASSWORD", "FEDERATED_IDENTITY_LINK_ERROR", "CLIENT_DELETE", "IDENTITY_PROVIDER_FIRST_LOGIN", "VERIFY_EMAIL", "CLIENT_DELETE_ERROR", "CLIENT_LOGIN_ERROR", "RESTART_AUTHENTICATION_ERROR", "REMOVE_FEDERATED_IDENTITY_ERROR", "EXECUTE_ACTIONS", "SEND_IDENTITY_PROVIDER_LINK_ERROR", "EXECUTE_ACTION_TOKEN_ERROR", "SEND_VERIFY_EMAIL", "EXECUTE_ACTIONS_ERROR", "REMOVE_FEDERATED_IDENTITY", "IDENTITY_PROVIDER_POST_LOGIN", "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", "UPDATE_EMAIL", "REGISTER_ERROR", "REVOKE_GRANT_ERROR", "LOGOUT_ERROR", "UPDATE_EMAIL_ERROR", "EXECUTE_ACTION_TOKEN", "CLIENT_UPDATE_ERROR", "UPDATE_PROFILE", "FEDERATED_IDENTITY_LINK", "CLIENT_REGISTER_ERROR", "SEND_VERIFY_EMAIL_ERROR", "SEND_IDENTITY_PROVIDER_LINK", "RESET_PASSWORD", "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", "REMOVE_TOTP_ERROR", "VERIFY_EMAIL_ERROR", "SEND_RESET_PASSWORD_ERROR", "CLIENT_UPDATE", "IDENTITY_PROVIDER_POST_LOGIN_ERROR", "CUSTOM_REQUIRED_ACTION_ERROR", "UPDATE_TOTP_ERROR", "CODE_TO_TOKEN", "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" ],
+   "adminEventsEnabled" : true,
+   "adminEventsDetailsEnabled" : true,
+   "requiredCredentials":[
+      "password"
+   ],
+   "passwordPolicy": "length(10) and lowerCase(1) and upperCase(1) and passwordHistory(3) and digits(1) and specialChars(1) and hashAlgorithm(pbkdf2-sha256)",
+   "users":[
+      {
+         "username":"user1",
+         "firstName" : "User",
+         "lastName" : "1",
+         "email" : "user1@feedhenry.org",
+         "enabled":true,
+         "credentials":[
+            {
+               "type":"password",
+               "value":"123"
+            }
+         ],
+         "clientRoles":{
+            "account":[
+               "view-profile",
+               "manage-account"
+            ]
+         },
+         "attributes":{
+
+         },
+        "groups" : [ "/Mobile Users" ]
+      },
+      {
+         "username":"user2",
+         "firstName" : "User",
+         "lastName" : "2",
+         "email" : "user2@feedhenry.org",
+         "enabled":true,
+         "credentials":[
+            {
+               "type":"password",
+               "value":"123"
+            }
+         ],
+         "clientRoles":{
+            "account":[
+               "view-profile",
+               "manage-account"
+            ]
+         },
+         "attributes":{
+
+         },
+         "groups" : [ "/Mobile Users" ]
+      },
+      {
+         "username":"secure-user",
+         "enabled" : true,
+          "emailVerified" : true,
+          "firstName" : "Secure",
+          "lastName" : "User",
+          "email" : "secure-user@feedhenry.org",
+         "credentials":[
+            {
+               "type":"password",
+               "value":"123"
+            }
+         ],
+         "requiredActions" : [ "CONFIGURE_TOTP" ],
+         "realmRoles" : [ ],
+         "clientRoles":{
+            "account":[
+               "view-profile",
+               "manage-account"
+            ]
+         },
+         "attributes":{
+
+         },
+         "groups" : [ "/Mobile Users", "/API Access" ]
+      },
+      {
+         "username":"secure-user2",
+         "enabled" : true,
+          "emailVerified" : true,
+          "firstName" : "Secure",
+          "lastName" : "User 2",
+          "email" : "secure-user2@feedhenry.org",
+         "credentials":[
+            {
+               "type":"password",
+               "value":"123"
+            }
+         ],
+         "requiredActions" : [ "CONFIGURE_TOTP" ],
+         "realmRoles" : [ ],
+         "clientRoles":{
+            "account":[
+               "view-profile",
+               "manage-account"
+            ]
+         },
+         "attributes":{
+
+         },
+         "groups" : [ "/Mobile Users", "/API Access" ]
+      },
+      {
+         "username":"superuser",
+         "enabled" : true,
+          "emailVerified" : true,
+          "firstName" : "Super",
+          "lastName" : "User",
+          "email" : "superuser@feedhenry.org",
+         "credentials":[
+            {
+               "type":"password",
+               "value":"123"
+            }
+         ],
+         "realmRoles" : [ ],
+         "clientRoles":{
+            "account":[
+               "view-profile",
+               "manage-account"
+            ]
+         },
+         "attributes":{
+
+         },
+         "groups" : [ "/Mobile Users", "/API Access", "Superuser" ]
+      }
+   ],
+   "clients":[
+      {
+         "clientId":"api-server",
+         "enabled":true,
+         "bearerOnly":true,
+         "adminUrl":"http://localhost:8080"
+      },
+      {
+         "clientId":"client-app",
+         "enabled":true,
+         "publicClient":true,
+         "redirectUris":[
+            "com.feedhenry.securenativeandroidtemplate:/callback"
+         ],
+         "webOrigins":[
+            "*"
+         ]
+      }
+   ],
+   "clientScopeMappings":{
+      "account":[
+         {
+            "client":"api-server",
+            "roles":[
+               "view-profile"
+            ]
+         },
+         {
+            "client":"client-app",
+            "roles":[
+               "view-profile"
+            ]
+         }
+      ]
+   },
+   "groups" : [ {
+     "name" : "Mobile Users",
+     "path" : "/Mobile Users",
+     "attributes" : { },
+     "realmRoles" : [ "mobile-user" ],
+     "clientRoles" : { },
+     "subGroups" : [ ]
+   },
+   {
+     "name" : "API Access",
+     "path" : "/API Access",
+     "attributes" : { },
+     "realmRoles" : [ "mobile-user", "api-access" ],
+     "clientRoles" : { },
+     "subGroups" : [ ]
+   },
+   {
+     "name" : "Superuser",
+     "path" : "/Superusers",
+     "attributes" : { },
+     "realmRoles" : [ "mobile-user", "api-access", "superuser" ],
+     "clientRoles" : { },
+     "subGroups" : [ ]
+   } ],
+   "roles":{
+      "client":{
+         "api-server":[
+
+         ],
+         "client-app":[
+
+         ]
+      }
+   },
+   "authenticationFlows" : [ {
+    "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",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "idp-email-verification",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "requirement" : "ALTERNATIVE",
+      "priority" : 30,
+      "flowAlias" : "Verify Existing Account by Re-authentication",
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : true
+    } ]
+  }, {
+    "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",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "auth-otp-form",
+      "requirement" : "OPTIONAL",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "X.509 Browser",
+    "description" : "browser based authentication",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : false,
+    "authenticationExecutions" : [ {
+      "authenticator" : "auth-cookie",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "auth-spnego",
+      "requirement" : "DISABLED",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticatorConfig" : "authenticator config",
+      "authenticator" : "identity-provider-redirector",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 25,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticatorConfig" : "x509 browser auth config",
+      "authenticator" : "auth-x509-client-username-form",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 30,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "requirement" : "ALTERNATIVE",
+      "priority" : 31,
+      "flowAlias" : "X.509 Browser forms",
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : true
+    } ]
+  }, {
+    "alias" : "X.509 Browser forms",
+    "description" : "Username, password, otp and other auth forms.",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : false,
+    "authenticationExecutions" : [ {
+      "authenticator" : "auth-username-password-form",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "auth-otp-form",
+      "requirement" : "OPTIONAL",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "X.509 Direct Grant",
+    "description" : "OpenID Connect Resource Owner Grant",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : false,
+    "authenticationExecutions" : [ {
+      "authenticatorConfig" : "x509 direct grant config",
+      "authenticator" : "direct-grant-auth-x509-username",
+      "requirement" : "REQUIRED",
+      "priority" : 0,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "browser",
+    "description" : "browser based authentication",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "auth-cookie",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "auth-spnego",
+      "requirement" : "DISABLED",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "identity-provider-redirector",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 25,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "requirement" : "ALTERNATIVE",
+      "priority" : 30,
+      "flowAlias" : "forms",
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : true
+    } ]
+  }, {
+    "alias" : "clients",
+    "description" : "Base authentication for clients",
+    "providerId" : "client-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "client-secret",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "client-jwt",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "direct grant",
+    "description" : "OpenID Connect Resource Owner Grant",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "direct-grant-validate-username",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "direct-grant-validate-password",
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "direct-grant-validate-otp",
+      "requirement" : "OPTIONAL",
+      "priority" : 30,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "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",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "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",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticatorConfig" : "create unique user config",
+      "authenticator" : "idp-create-user-if-unique",
+      "requirement" : "ALTERNATIVE",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "requirement" : "ALTERNATIVE",
+      "priority" : 30,
+      "flowAlias" : "Handle Existing Account",
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : true
+    } ]
+  }, {
+    "alias" : "forms",
+    "description" : "Username, password, otp and other auth forms.",
+    "providerId" : "basic-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "auth-username-password-form",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "auth-otp-form",
+      "requirement" : "OPTIONAL",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "registration",
+    "description" : "registration flow",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "registration-page-form",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "flowAlias" : "registration form",
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : true
+    } ]
+  }, {
+    "alias" : "registration form",
+    "description" : "registration form",
+    "providerId" : "form-flow",
+    "topLevel" : false,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "registration-user-creation",
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "registration-profile-action",
+      "requirement" : "REQUIRED",
+      "priority" : 40,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "registration-password-action",
+      "requirement" : "REQUIRED",
+      "priority" : 50,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "registration-recaptcha-action",
+      "requirement" : "DISABLED",
+      "priority" : 60,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "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",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "reset-credential-email",
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "reset-password",
+      "requirement" : "REQUIRED",
+      "priority" : 30,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    }, {
+      "authenticator" : "reset-otp",
+      "requirement" : "OPTIONAL",
+      "priority" : 40,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  }, {
+    "alias" : "saml ecp",
+    "description" : "SAML ECP Profile Authentication Flow",
+    "providerId" : "basic-flow",
+    "topLevel" : true,
+    "builtIn" : true,
+    "authenticationExecutions" : [ {
+      "authenticator" : "http-basic-authenticator",
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "userSetupAllowed" : false,
+      "autheticatorFlow" : false
+    } ]
+  } ],
+  "authenticatorConfig" : [ {
+    "alias" : "authenticator config",
+    "config" : {
+      "defaultProvider" : ""
+    }
+  }, {
+    "alias" : "create unique user config",
+    "config" : {
+      "require.password.update.after.registration" : "false"
+    }
+  }, {
+    "alias" : "review profile config",
+    "config" : {
+      "update.profile.on.first.login" : "missing"
+    }
+  }, {
+    "alias" : "x509 browser auth config",
+    "config" : {
+      "x509-cert-auth.extendedkeyusage" : "",
+      "x509-cert-auth.mapper-selection.user-attribute-name" : "usercertificate",
+      "x509-cert-auth.ocsp-responder-uri" : "",
+      "x509-cert-auth.regular-expression" : "(.*?)(?:$)",
+      "x509-cert-auth.crl-checking-enabled" : "",
+      "x509-cert-auth.confirmation-page-disallowed" : "",
+      "x509-cert-auth.keyusage" : "",
+      "x509-cert-auth.mapper-selection" : "Username or Email",
+      "x509-cert-auth.crl-relative-path" : "crl.pem",
+      "x509-cert-auth.crldp-checking-enabled" : "false",
+      "x509-cert-auth.mapping-source-selection" : "Subject's Common Name",
+      "x509-cert-auth.ocsp-checking-enabled" : ""
+    }
+  }, {
+    "alias" : "x509 direct grant config",
+    "config" : {
+      "x509-cert-auth.extendedkeyusage" : "",
+      "x509-cert-auth.mapper-selection.user-attribute-name" : "usercertificate",
+      "x509-cert-auth.ocsp-responder-uri" : "",
+      "x509-cert-auth.regular-expression" : "(.*?)(?:$)",
+      "x509-cert-auth.crl-checking-enabled" : "",
+      "x509-cert-auth.confirmation-page-disallowed" : "",
+      "x509-cert-auth.keyusage" : "",
+      "x509-cert-auth.mapper-selection" : "Username or Email",
+      "x509-cert-auth.crl-relative-path" : "crl.pem",
+      "x509-cert-auth.crldp-checking-enabled" : "false",
+      "x509-cert-auth.mapping-source-selection" : "Subject's Common Name",
+      "x509-cert-auth.ocsp-checking-enabled" : ""
+    }
+  } ]
+}