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"> -
-
-
- -
- -
- -
-
- -
-
-
-
-
- -
-
- -
-
-
-
- - \ 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"> -
-
-
- -
- -
- -
-
- -
-
-
-
-
- -
-
- value="${auth.selectedCredential}"/> - -
-
-
-
- - \ 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