diff --git a/docs/documentation/server_development/topics/auth-spi.adoc b/docs/documentation/server_development/topics/auth-spi.adoc
index eae0b6d21f..509c244837 100644
--- a/docs/documentation/server_development/topics/auth-spi.adoc
+++ b/docs/documentation/server_development/topics/auth-spi.adoc
@@ -151,7 +151,7 @@ Let's walk through the steps from when a client first redirects to keycloak to a
In this section, we'll take a look at the Authenticator interface.
For this, we are going to implement an authenticator that requires that a user enter in the answer to a secret question like "What is your mother's maiden name?".
-This example is fully implemented and contained in the examples/providers/authenticator directory of the demo distribution of {project_name}.
+This example is fully implemented and contained in the {quickstartRepo_link}[{quickstartRepo_name}] repository under `extension/authenticator`.
To create an authenticator, you must at minimum implement the org.keycloak.authentication.AuthenticatorFactory and Authenticator interfaces.
The Authenticator interface defines the logic. The AuthenticatorFactory is responsible for creating instances of an Authenticator.
diff --git a/examples/providers/authenticator/README.md b/examples/providers/authenticator/README.md
deleted file mode 100755
index 98b01c961b..0000000000
--- a/examples/providers/authenticator/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-Example Custom Authenticator
-===================================================
-
-1. First, Keycloak must be running. See [Getting Started](https://github.com/keycloak/keycloak#getting-started), or you
- can build distribution from [source](https://github.com/keycloak/keycloak/blob/main/docs/building.md).
-
-2. Execute the follow. This will build the example and deploy it
-
- `$ mvn clean install wildfly:deploy`
-
-3. Copy the `secret-question.ftl` and `secret-question-config.ftl` files to the `themes/base/login` server directory.
-
-4. Login to admin console. Hit browser refresh if you are already logged in so that the new providers show up.
-
-5. Go to the **Authentication** menu item and go to the **Flows** tab, you will be able to view the currently
- defined flows. You cannot modify a built-in flows, so, to add the Authenticator you
- have to copy an existing flow or create your own. Copy the "Browser" flow.
-
-6. In your copy, click the **Actions** menu item in **Forms** subflow and **Add Execution**. Pick `Secret Question` and change
- the **Requirement** choice.
-
-7. Go to the **Bindings** tab in **Authentication** menu and change the default **Browser Flow** to your copy of the browser flow
- and click `Save`.
-
-8. Next you have to register the required action that you created. Click on the **Required Actions** tab in the **Authentication** menu.
- Click on the `Register` button and choose your new Required Action. You can also choose the `Default Action` for the Required Action
- and each new user has to set the secret answer.
- Your new required action should now be displayed and enabled in the required actions list.
-
diff --git a/examples/providers/authenticator/pom.xml b/examples/providers/authenticator/pom.xml
deleted file mode 100755
index dc87b6705f..0000000000
--- a/examples/providers/authenticator/pom.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
- keycloak-examples-providers-parent
- org.keycloak
- 999.0.0-SNAPSHOT
-
-
- Authenticator Example
-
- 4.0.0
-
- authenticator-required-action-example
- jar
-
-
-
- org.keycloak
- keycloak-core
- provided
-
-
- org.keycloak
- keycloak-server-spi
- provided
-
-
- org.keycloak
- keycloak-server-spi-private
- provided
-
-
- org.jboss.logging
- jboss-logging
- provided
-
-
- org.keycloak
- keycloak-services
- provided
-
-
-
-
- authenticator-required-action-example
-
-
- org.wildfly.plugins
- wildfly-maven-plugin
-
- false
-
-
-
-
-
diff --git a/examples/providers/authenticator/secret-question-config.ftl b/examples/providers/authenticator/secret-question-config.ftl
deleted file mode 100755
index 54e69026b0..0000000000
--- a/examples/providers/authenticator/secret-question-config.ftl
+++ /dev/null
@@ -1,33 +0,0 @@
-<#import "template.ftl" as layout>
-<@layout.registrationLayout; section>
- <#if section = "title">
- ${msg("loginTitle",realm.name)}
- <#elseif section = "header">
- Setup Secret Question
- <#elseif section = "form">
-
- #if>
-@layout.registrationLayout>
\ No newline at end of file
diff --git a/examples/providers/authenticator/secret-question.ftl b/examples/providers/authenticator/secret-question.ftl
deleted file mode 100755
index b8ca1c901a..0000000000
--- a/examples/providers/authenticator/secret-question.ftl
+++ /dev/null
@@ -1,35 +0,0 @@
-<#import "template.ftl" as layout>
-<@layout.registrationLayout; section>
- <#if section = "title">
- ${msg("loginTitle",realm.name)}
- <#elseif section = "header">
- ${msg("loginTitleHtml",realm.name)}
- <#elseif section = "form">
-
- #if>
-@layout.registrationLayout>
\ No newline at end of file
diff --git a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionAuthenticator.java b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionAuthenticator.java
deleted file mode 100755
index d423eba567..0000000000
--- a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionAuthenticator.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.examples.authenticator;
-
-import org.keycloak.http.HttpResponse;
-import org.keycloak.authentication.AuthenticationFlowContext;
-import org.keycloak.authentication.AuthenticationFlowError;
-import org.keycloak.authentication.Authenticator;
-import org.keycloak.authentication.CredentialValidator;
-import org.keycloak.authentication.RequiredActionFactory;
-import org.keycloak.authentication.RequiredActionProvider;
-import org.keycloak.credential.CredentialProvider;
-import org.keycloak.models.AuthenticatorConfigModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
-
-import jakarta.ws.rs.core.Cookie;
-import jakarta.ws.rs.core.MultivaluedMap;
-import jakarta.ws.rs.core.NewCookie;
-import jakarta.ws.rs.core.Response;
-import java.net.URI;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class SecretQuestionAuthenticator implements Authenticator, CredentialValidator {
-
- protected boolean hasCookie(AuthenticationFlowContext context) {
- Cookie cookie = context.getHttpRequest().getHttpHeaders().getCookies().get("SECRET_QUESTION_ANSWERED");
- boolean result = cookie != null;
- if (result) {
- System.out.println("Bypassing secret question because cookie is set");
- }
- return result;
- }
-
- @Override
- public void authenticate(AuthenticationFlowContext context) {
- if (hasCookie(context)) {
- context.success();
- return;
- }
- Response challenge = context.form()
- .createForm("secret-question.ftl");
- context.challenge(challenge);
- }
-
- @Override
- public void action(AuthenticationFlowContext context) {
- boolean validated = validateAnswer(context);
- if (!validated) {
- Response challenge = context.form()
- .setError("badSecret")
- .createForm("secret-question.ftl");
- context.failureChallenge(AuthenticationFlowError.INVALID_CREDENTIALS, challenge);
- return;
- }
- setCookie(context);
- context.success();
- }
-
- protected void setCookie(AuthenticationFlowContext context) {
- AuthenticatorConfigModel config = context.getAuthenticatorConfig();
- int maxCookieAge = 60 * 60 * 24 * 30; // 30 days
- if (config != null) {
- maxCookieAge = Integer.valueOf(config.getConfig().get("cookie.max.age"));
-
- }
- URI uri = context.getUriInfo().getBaseUriBuilder().path("realms").path(context.getRealm().getName()).build();
- addCookie(context, "SECRET_QUESTION_ANSWERED", "true",
- uri.getRawPath(),
- null, null,
- maxCookieAge,
- false, true);
- }
-
- public void addCookie(AuthenticationFlowContext context, String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly) {
- HttpResponse response = context.getSession().getContext().getHttpResponse();
- response.setCookieIfAbsent(new NewCookie.Builder(name)
- .version(1)
- .path(path)
- .domain(domain)
- .comment(comment)
- .maxAge(maxAge)
- .secure(secure)
- .httpOnly(httpOnly)
- .sameSite(null)
- .build());
- }
-
-
- protected boolean validateAnswer(AuthenticationFlowContext context) {
- MultivaluedMap formData = context.getHttpRequest().getDecodedFormParameters();
- String secret = formData.getFirst("secret_answer");
- String credentialId = formData.getFirst("credentialId");
- if (credentialId == null || credentialId.isEmpty()) {
- credentialId = getCredentialProvider(context.getSession())
- .getDefaultCredential(context.getSession(), context.getRealm(), context.getUser()).getId();
- }
-
- UserCredentialModel input = new UserCredentialModel(credentialId, getType(context.getSession()), secret);
- return getCredentialProvider(context.getSession()).isValid(context.getRealm(), context.getUser(), input);
- }
-
- @Override
- public boolean requiresUser() {
- return true;
- }
-
- @Override
- public boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user) {
- return getCredentialProvider(session).isConfiguredFor(realm, user, getType(session));
- }
-
- @Override
- public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {
- user.addRequiredAction(SecretQuestionRequiredAction.PROVIDER_ID);
- }
-
- public List getRequiredActions(KeycloakSession session) {
- return Collections.singletonList((SecretQuestionRequiredActionFactory)session.getKeycloakSessionFactory().getProviderFactory(RequiredActionProvider.class, SecretQuestionRequiredAction.PROVIDER_ID));
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public SecretQuestionCredentialProvider getCredentialProvider(KeycloakSession session) {
- return (SecretQuestionCredentialProvider)session.getProvider(CredentialProvider.class, SecretQuestionCredentialProviderFactory.PROVIDER_ID);
- }
-}
diff --git a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionAuthenticatorFactory.java b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionAuthenticatorFactory.java
deleted file mode 100755
index 9b6bc659df..0000000000
--- a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionAuthenticatorFactory.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.examples.authenticator;
-
-import org.keycloak.Config;
-import org.keycloak.authentication.Authenticator;
-import org.keycloak.authentication.AuthenticatorFactory;
-import org.keycloak.authentication.ConfigurableAuthenticatorFactory;
-import org.keycloak.models.AuthenticationExecutionModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.provider.ProviderConfigProperty;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class SecretQuestionAuthenticatorFactory implements AuthenticatorFactory, ConfigurableAuthenticatorFactory {
-
- public static final String PROVIDER_ID = "secret-question-authenticator";
- private static final SecretQuestionAuthenticator SINGLETON = new SecretQuestionAuthenticator();
-
- @Override
- public String getId() {
- return PROVIDER_ID;
- }
-
- @Override
- public Authenticator create(KeycloakSession session) {
- return SINGLETON;
- }
-
- private static AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = {
- AuthenticationExecutionModel.Requirement.REQUIRED,
- AuthenticationExecutionModel.Requirement.ALTERNATIVE,
- AuthenticationExecutionModel.Requirement.DISABLED
- };
- @Override
- public AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
- return REQUIREMENT_CHOICES;
- }
-
- @Override
- public boolean isUserSetupAllowed() {
- return true;
- }
-
- @Override
- public boolean isConfigurable() {
- return true;
- }
-
- @Override
- public List getConfigProperties() {
- return configProperties;
- }
-
- private static final List configProperties = new ArrayList();
-
- static {
- ProviderConfigProperty property;
- property = new ProviderConfigProperty();
- property.setName("cookie.max.age");
- property.setLabel("Cookie Max Age");
- property.setType(ProviderConfigProperty.STRING_TYPE);
- property.setHelpText("Max age in seconds of the SECRET_QUESTION_COOKIE.");
- configProperties.add(property);
- }
-
-
- @Override
- public String getHelpText() {
- return "A secret question that a user has to answer. i.e. What is your mother's maiden name.";
- }
-
- @Override
- public String getDisplayType() {
- return "Secret Question";
- }
-
- @Override
- public String getReferenceCategory() {
- return "Secret Question";
- }
-
- @Override
- public void init(Config.Scope config) {
-
- }
-
- @Override
- public void postInit(KeycloakSessionFactory factory) {
-
- }
-
- @Override
- public void close() {
-
- }
-
-
-}
diff --git a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProvider.java b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProvider.java
deleted file mode 100644
index 2d0dc68c81..0000000000
--- a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProvider.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.examples.authenticator;
-
-import org.jboss.logging.Logger;
-import org.keycloak.common.util.Time;
-import org.keycloak.credential.CredentialInput;
-import org.keycloak.credential.CredentialInputValidator;
-import org.keycloak.credential.CredentialModel;
-import org.keycloak.credential.CredentialProvider;
-import org.keycloak.credential.CredentialTypeMetadata;
-import org.keycloak.credential.CredentialTypeMetadataContext;
-import org.keycloak.examples.authenticator.credential.SecretQuestionCredentialModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class SecretQuestionCredentialProvider implements CredentialProvider, CredentialInputValidator {
- private static final Logger logger = Logger.getLogger(SecretQuestionCredentialProvider.class);
-
- protected KeycloakSession session;
-
- public SecretQuestionCredentialProvider(KeycloakSession session) {
- this.session = session;
- }
-
- @Override
- public boolean isValid(RealmModel realm, UserModel user, CredentialInput input) {
- if (!(input instanceof UserCredentialModel)) {
- logger.debug("Expected instance of UserCredentialModel for CredentialInput");
- return false;
- }
- if (!input.getType().equals(getType())) {
- return false;
- }
- String challengeResponse = input.getChallengeResponse();
- if (challengeResponse == null) {
- return false;
- }
- CredentialModel credentialModel = user.credentialManager().getStoredCredentialById(input.getCredentialId());
- SecretQuestionCredentialModel sqcm = getCredentialFromModel(credentialModel);
- return sqcm.getSecretQuestionSecretData().getAnswer().equals(challengeResponse);
- }
-
- @Override
- public boolean supportsCredentialType(String credentialType) {
- return getType().equals(credentialType);
- }
-
- @Override
- public boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType) {
- if (!supportsCredentialType(credentialType)) return false;
- return user.credentialManager().getStoredCredentialsByTypeStream(credentialType).findAny().isPresent();
- }
-
- @Override
- public CredentialModel createCredential(RealmModel realm, UserModel user, SecretQuestionCredentialModel credentialModel) {
- if (credentialModel.getCreatedDate() == null) {
- credentialModel.setCreatedDate(Time.currentTimeMillis());
- }
- return user.credentialManager().createStoredCredential(credentialModel);
- }
-
- @Override
- public boolean deleteCredential(RealmModel realm, UserModel user, String credentialId) {
- return user.credentialManager().removeStoredCredentialById(credentialId);
- }
-
- @Override
- public SecretQuestionCredentialModel getCredentialFromModel(CredentialModel model) {
- return SecretQuestionCredentialModel.createFromCredentialModel(model);
- }
-
- @Override
- public CredentialTypeMetadata getCredentialTypeMetadata(CredentialTypeMetadataContext metadataContext) {
- return CredentialTypeMetadata.builder()
- .type(getType())
- .category(CredentialTypeMetadata.Category.TWO_FACTOR)
- .displayName(SecretQuestionCredentialProviderFactory.PROVIDER_ID)
- .helpText("secret-question-text")
- .createAction(SecretQuestionAuthenticatorFactory.PROVIDER_ID)
- .removeable(false)
- .build(session);
- }
-
- @Override
- public String getType() {
- return SecretQuestionCredentialModel.TYPE;
- }
-}
diff --git a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProviderFactory.java b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProviderFactory.java
deleted file mode 100644
index 573d26d80c..0000000000
--- a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProviderFactory.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.examples.authenticator;
-
-import org.keycloak.credential.CredentialProvider;
-import org.keycloak.credential.CredentialProviderFactory;
-import org.keycloak.models.KeycloakSession;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class SecretQuestionCredentialProviderFactory implements CredentialProviderFactory {
-
- public static final String PROVIDER_ID = "secret-question";
-
- @Override
- public String getId() {
- return PROVIDER_ID;
- }
-
- @Override
- public CredentialProvider create(KeycloakSession session) {
- return new SecretQuestionCredentialProvider(session);
- }
-}
diff --git a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionRequiredAction.java b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionRequiredAction.java
deleted file mode 100755
index 1463ed629c..0000000000
--- a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionRequiredAction.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.examples.authenticator;
-
-import org.keycloak.authentication.CredentialRegistrator;
-import org.keycloak.authentication.RequiredActionContext;
-import org.keycloak.authentication.RequiredActionProvider;
-import org.keycloak.credential.CredentialProvider;
-import org.keycloak.examples.authenticator.credential.SecretQuestionCredentialModel;
-
-import jakarta.ws.rs.core.Response;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class SecretQuestionRequiredAction implements RequiredActionProvider, CredentialRegistrator {
- public static final String PROVIDER_ID = "secret_question_config";
-
- @Override
- public void evaluateTriggers(RequiredActionContext context) {
-
- }
-
- @Override
- public void requiredActionChallenge(RequiredActionContext context) {
- Response challenge = context.form().createForm("secret-question-config.ftl");
- context.challenge(challenge);
-
- }
-
- @Override
- public void processAction(RequiredActionContext context) {
- String answer = (context.getHttpRequest().getDecodedFormParameters().getFirst("secret_answer"));
- SecretQuestionCredentialProvider sqcp = (SecretQuestionCredentialProvider) context.getSession().getProvider(CredentialProvider.class, "secret-question");
- sqcp.createCredential(context.getRealm(), context.getUser(), SecretQuestionCredentialModel.createSecretQuestion("What is your mom's first name?", answer));
- context.success();
- }
-
- @Override
- public void close() {
-
- }
-}
diff --git a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionRequiredActionFactory.java b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionRequiredActionFactory.java
deleted file mode 100755
index 46ad4ebc75..0000000000
--- a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionRequiredActionFactory.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.examples.authenticator;
-
-import org.keycloak.Config;
-import org.keycloak.authentication.RequiredActionFactory;
-import org.keycloak.authentication.RequiredActionProvider;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-
-/**
- * @author Bill Burke
- * @version $Revision: 1 $
- */
-public class SecretQuestionRequiredActionFactory implements RequiredActionFactory {
-
- private static final SecretQuestionRequiredAction SINGLETON = new SecretQuestionRequiredAction();
-
- @Override
- public RequiredActionProvider create(KeycloakSession session) {
- return SINGLETON;
- }
-
-
- @Override
- public String getId() {
- return SecretQuestionRequiredAction.PROVIDER_ID;
- }
-
- @Override
- public String getDisplayText() {
- return "Secret Question";
- }
-
- @Override
- public void init(Config.Scope config) {
-
- }
-
- @Override
- public void postInit(KeycloakSessionFactory factory) {
-
- }
-
- @Override
- public void close() {
-
- }
-
-}
diff --git a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/credential/SecretQuestionCredentialModel.java b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/credential/SecretQuestionCredentialModel.java
deleted file mode 100644
index 8cca82e523..0000000000
--- a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/credential/SecretQuestionCredentialModel.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.examples.authenticator.credential;
-
-import org.keycloak.common.util.Time;
-import org.keycloak.credential.CredentialModel;
-import org.keycloak.examples.authenticator.credential.dto.SecretQuestionCredentialData;
-import org.keycloak.examples.authenticator.credential.dto.SecretQuestionSecretData;
-import org.keycloak.util.JsonSerialization;
-
-import java.io.IOException;
-
-/**
- * @author Alistair Doswald
- * @version $Revision: 1 $
- */
-public class SecretQuestionCredentialModel extends CredentialModel {
- public static final String TYPE = "SECRET_QUESTION";
-
- private final SecretQuestionCredentialData credentialData;
- private final SecretQuestionSecretData secretData;
-
- private SecretQuestionCredentialModel(SecretQuestionCredentialData credentialData, SecretQuestionSecretData secretData) {
- this.credentialData = credentialData;
- this.secretData = secretData;
- }
-
- private SecretQuestionCredentialModel(String question, String answer) {
- credentialData = new SecretQuestionCredentialData(question);
- secretData = new SecretQuestionSecretData(answer);
- }
-
- public static SecretQuestionCredentialModel createSecretQuestion(String question, String answer) {
- SecretQuestionCredentialModel credentialModel = new SecretQuestionCredentialModel(question, answer);
- credentialModel.fillCredentialModelFields();
- return credentialModel;
- }
-
- public static SecretQuestionCredentialModel createFromCredentialModel(CredentialModel credentialModel){
- try {
- SecretQuestionCredentialData credentialData = JsonSerialization.readValue(credentialModel.getCredentialData(), SecretQuestionCredentialData.class);
- SecretQuestionSecretData secretData = JsonSerialization.readValue(credentialModel.getSecretData(), SecretQuestionSecretData.class);
-
- SecretQuestionCredentialModel secretQuestionCredentialModel = new SecretQuestionCredentialModel(credentialData, secretData);
- secretQuestionCredentialModel.setUserLabel(credentialModel.getUserLabel());
- secretQuestionCredentialModel.setCreatedDate(credentialModel.getCreatedDate());
- secretQuestionCredentialModel.setType(TYPE);
- secretQuestionCredentialModel.setId(credentialModel.getId());
- secretQuestionCredentialModel.setSecretData(credentialModel.getSecretData());
- secretQuestionCredentialModel.setCredentialData(credentialModel.getCredentialData());
- return secretQuestionCredentialModel;
- } catch (IOException e){
- throw new RuntimeException(e);
- }
- }
-
- public SecretQuestionCredentialData getSecretQuestionCredentialData() {
- return credentialData;
- }
-
- public SecretQuestionSecretData getSecretQuestionSecretData() {
- return secretData;
- }
-
- private void fillCredentialModelFields(){
- try {
- setCredentialData(JsonSerialization.writeValueAsString(credentialData));
- setSecretData(JsonSerialization.writeValueAsString(secretData));
- setType(TYPE);
- setCreatedDate(Time.currentTimeMillis());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-}
diff --git a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/credential/dto/SecretQuestionCredentialData.java b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/credential/dto/SecretQuestionCredentialData.java
deleted file mode 100644
index 05033eb3a9..0000000000
--- a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/credential/dto/SecretQuestionCredentialData.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.examples.authenticator.credential.dto;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * @author Alistair Doswald
- * @version $Revision: 1 $
- */
-public class SecretQuestionCredentialData {
-
- private final String question;
-
- @JsonCreator
- public SecretQuestionCredentialData(@JsonProperty("question") String question) {
- this.question = question;
- }
-
- public String getQuestion() {
- return question;
- }
-}
diff --git a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/credential/dto/SecretQuestionSecretData.java b/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/credential/dto/SecretQuestionSecretData.java
deleted file mode 100644
index 9c592ee4ae..0000000000
--- a/examples/providers/authenticator/src/main/java/org/keycloak/examples/authenticator/credential/dto/SecretQuestionSecretData.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.examples.authenticator.credential.dto;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * @author Alistair Doswald
- * @version $Revision: 1 $
- */
-public class SecretQuestionSecretData {
-
- private final String answer;
-
- @JsonCreator
- public SecretQuestionSecretData(@JsonProperty("answer") String answer) {
- this.answer = answer;
- }
-
- public String getAnswer() {
- return answer;
- }
-}
diff --git a/examples/providers/authenticator/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory b/examples/providers/authenticator/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory
deleted file mode 100755
index f288d3daa9..0000000000
--- a/examples/providers/authenticator/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# 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.
-#
-
-org.keycloak.examples.authenticator.SecretQuestionAuthenticatorFactory
\ No newline at end of file
diff --git a/examples/providers/authenticator/src/main/resources/META-INF/services/org.keycloak.authentication.RequiredActionFactory b/examples/providers/authenticator/src/main/resources/META-INF/services/org.keycloak.authentication.RequiredActionFactory
deleted file mode 100755
index 034c2f17c2..0000000000
--- a/examples/providers/authenticator/src/main/resources/META-INF/services/org.keycloak.authentication.RequiredActionFactory
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# 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.
-#
-
-org.keycloak.examples.authenticator.SecretQuestionRequiredActionFactory
\ No newline at end of file
diff --git a/examples/providers/authenticator/src/main/resources/META-INF/services/org.keycloak.credential.CredentialProviderFactory b/examples/providers/authenticator/src/main/resources/META-INF/services/org.keycloak.credential.CredentialProviderFactory
deleted file mode 100644
index a221e371cc..0000000000
--- a/examples/providers/authenticator/src/main/resources/META-INF/services/org.keycloak.credential.CredentialProviderFactory
+++ /dev/null
@@ -1 +0,0 @@
- org.keycloak.examples.authenticator.SecretQuestionCredentialProviderFactory
\ No newline at end of file
diff --git a/examples/providers/pom.xml b/examples/providers/pom.xml
index 198116d57c..231b2aa4b8 100755
--- a/examples/providers/pom.xml
+++ b/examples/providers/pom.xml
@@ -32,6 +32,5 @@
rest
- authenticator