keycloak-aplcache

Changes

services/src/main/java/org/keycloak/authentication/authenticators/LoginFormOTPAuthenticator.java 82(+0 -82)

services/src/main/java/org/keycloak/authentication/authenticators/LoginFormOTPAuthenticatorFactory.java 93(+0 -93)

services/src/main/java/org/keycloak/authentication/authenticators/LoginFormPasswordAuthenticator.java 84(+0 -84)

services/src/main/java/org/keycloak/authentication/authenticators/LoginFormUsernameAuthenticatorFactory.java 92(+0 -92)

Details

diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/AuthenticatorConfiguredMethod.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/AuthenticatorConfiguredMethod.java
index 7327e79..222252e 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/AuthenticatorConfiguredMethod.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/AuthenticatorConfiguredMethod.java
@@ -3,15 +3,10 @@ package org.keycloak.login.freemarker;
 import freemarker.template.TemplateMethodModelEx;
 import freemarker.template.TemplateModelException;
 import org.keycloak.authentication.Authenticator;
-import org.keycloak.authentication.AuthenticatorUtil;
-import org.keycloak.authentication.authenticators.LoginFormPasswordAuthenticatorFactory;
-import org.keycloak.models.AuthenticationExecutionModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.services.Urls;
 
-import java.net.URI;
 import java.util.List;
 
 /**
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/UrlBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/UrlBean.java
index c652002..25a28c9 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/UrlBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/UrlBean.java
@@ -48,7 +48,7 @@ public class UrlBean {
         if (this.actionuri != null) {
             return this.actionuri.toString();
         }
-        return Urls.realmLoginAction(baseURI, realm).toString();
+        throw new RuntimeException("action URI not set");
     }
 
     public String getLoginUrl() {
diff --git a/model/api/src/main/java/org/keycloak/models/utils/DefaultAuthenticationFlows.java b/model/api/src/main/java/org/keycloak/models/utils/DefaultAuthenticationFlows.java
index f4bb81c..48c5d61 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/DefaultAuthenticationFlows.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/DefaultAuthenticationFlows.java
@@ -19,22 +19,17 @@ public class DefaultAuthenticationFlows {
         model.setProviderId("auth-cookie");
         model.setAlias("Cookie");
         AuthenticatorModel cookieAuth = realm.addAuthenticator(model);
+
         model = new AuthenticatorModel();
-        model.setProviderId("auth-login-form-otp");
-        model.setAlias("Login Form OTP");
-        AuthenticatorModel loginFormOtp = realm.addAuthenticator(model);
-        model = new AuthenticatorModel();
-        model.setProviderId("auth-login-form-password");
-        model.setAlias("Login Form Password");
-        AuthenticatorModel password = realm.addAuthenticator(model);
-        model = new AuthenticatorModel();
-        model.setProviderId("auth-login-form-username");
-        model.setAlias("Login Form Username");
-        AuthenticatorModel username = realm.addAuthenticator(model);
+        model.setProviderId("auth-username-password-form");
+        model.setAlias("Username Password Form");
+        AuthenticatorModel usernamePasswordForm = realm.addAuthenticator(model);
+
         model = new AuthenticatorModel();
         model.setProviderId("auth-otp-form");
         model.setAlias("Single OTP Form");
-        AuthenticatorModel otp = realm.addAuthenticator(model);
+        AuthenticatorModel otpForm = realm.addAuthenticator(model);
+
         model = new AuthenticatorModel();
         model.setProviderId("auth-spnego");
         model.setAlias("Kerberos");
@@ -48,7 +43,7 @@ public class DefaultAuthenticationFlows {
         execution.setParentFlow(browser.getId());
         execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
         execution.setAuthenticator(cookieAuth.getId());
-        execution.setPriority(0);
+        execution.setPriority(10);
         execution.setUserSetupAllowed(false);
         execution.setAutheticatorFlow(false);
         realm.addAuthenticatorExecution(execution);
@@ -56,10 +51,12 @@ public class DefaultAuthenticationFlows {
         execution.setParentFlow(browser.getId());
         execution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED);
         execution.setAuthenticator(kerberos.getId());
-        execution.setPriority(1);
+        execution.setPriority(20);
         execution.setUserSetupAllowed(false);
         execution.setAutheticatorFlow(false);
         realm.addAuthenticatorExecution(execution);
+
+
         AuthenticationFlowModel forms = new AuthenticationFlowModel();
         forms.setAlias(FORMS_FLOW);
         forms.setDescription("Username, password, otp and other auth forms.");
@@ -68,38 +65,28 @@ public class DefaultAuthenticationFlows {
         execution.setParentFlow(browser.getId());
         execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
         execution.setAuthenticator(forms.getId());
-        execution.setPriority(2);
+        execution.setPriority(30);
         execution.setUserSetupAllowed(false);
         execution.setAutheticatorFlow(true);
         realm.addAuthenticatorExecution(execution);
 
         // forms
-        // Username processing
+        // Username Password processing
         execution = new AuthenticationExecutionModel();
         execution.setParentFlow(forms.getId());
         execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
-        execution.setAuthenticator(username.getId());
+        execution.setAuthenticator(usernamePasswordForm.getId());
         execution.setPriority(10);
         execution.setUserSetupAllowed(false);
         execution.setAutheticatorFlow(false);
         realm.addAuthenticatorExecution(execution);
 
-        // password processing
-        execution = new AuthenticationExecutionModel();
-        execution.setParentFlow(forms.getId());
-        execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
-        execution.setAuthenticator(password.getId());
-        execution.setPriority(11);
-        execution.setUserSetupAllowed(true);
-        execution.setAutheticatorFlow(false);
-        realm.addAuthenticatorExecution(execution);
-
         // otp processing
         execution = new AuthenticationExecutionModel();
         execution.setParentFlow(forms.getId());
         execution.setRequirement(AuthenticationExecutionModel.Requirement.OPTIONAL);
-        execution.setAuthenticator(otp.getId());
-        execution.setPriority(12);
+        execution.setAuthenticator(otpForm.getId());
+        execution.setPriority(20);
         execution.setUserSetupAllowed(true);
         execution.setAutheticatorFlow(false);
         realm.addAuthenticatorExecution(execution);
diff --git a/services/src/main/java/org/keycloak/authentication/AuthenticatorFactory.java b/services/src/main/java/org/keycloak/authentication/AuthenticatorFactory.java
index a6ac452..32414ab 100755
--- a/services/src/main/java/org/keycloak/authentication/AuthenticatorFactory.java
+++ b/services/src/main/java/org/keycloak/authentication/AuthenticatorFactory.java
@@ -13,7 +13,6 @@ import java.util.List;
 */
 public interface AuthenticatorFactory extends ProviderFactory<Authenticator>, ConfiguredProvider {
     Authenticator create(AuthenticatorModel model);
-    String getDisplayCategory();
     String getDisplayType();
 
     /**
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/AbstractFormAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/AbstractFormAuthenticator.java
index 9184034..6c611b1 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/AbstractFormAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/AbstractFormAuthenticator.java
@@ -3,14 +3,22 @@ package org.keycloak.authentication.authenticators;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.authentication.AuthenticationProcessor;
 import org.keycloak.authentication.AuthenticatorContext;
+import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.login.LoginFormsProvider;
+import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.messages.Messages;
 import org.keycloak.services.resources.LoginActionsService;
 
+import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import java.net.URI;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -21,6 +29,7 @@ public class AbstractFormAuthenticator {
     public static final String LOGIN_FORM_ACTION = "login_form";
     public static final String REGISTRATION_FORM_ACTION = "registration_form";
     public static final String ACTION = "action";
+    public static final String FORM_USERNAME = "FORM_USERNAME";
 
     protected boolean isAction(AuthenticatorContext context, String action) {
         return action.equals(context.getAction());
@@ -92,4 +101,50 @@ public class AbstractFormAuthenticator {
         }
         return false;
     }
+
+    public boolean validateUser(AuthenticatorContext context, MultivaluedMap<String, String> inputData) {
+        String username = inputData.getFirst(AuthenticationManager.FORM_USERNAME);
+        if (username == null) {
+            context.getEvent().error(Errors.USER_NOT_FOUND);
+            Response challengeResponse = invalidUser(context);
+            context.failureChallenge(AuthenticationProcessor.Error.INVALID_USER, challengeResponse);
+            return false;
+        }
+        context.getEvent().detail(Details.USERNAME, username);
+        context.getClientSession().setNote(AbstractFormAuthenticator.FORM_USERNAME, username);
+        UserModel user = KeycloakModelUtils.findUserByNameOrEmail(context.getSession(), context.getRealm(), username);
+        if (invalidUser(context, user)) return false;
+        String rememberMe = inputData.getFirst("rememberMe");
+        boolean remember = rememberMe != null && rememberMe.equalsIgnoreCase("on");
+        if (remember) {
+            context.getClientSession().setNote(Details.REMEMBER_ME, "true");
+            context.getEvent().detail(Details.REMEMBER_ME, "true");
+        }
+        context.setUser(user);
+        return true;
+    }
+
+    public boolean validatePassword(AuthenticatorContext context, MultivaluedMap<String, String> inputData) {
+        List<UserCredentialModel> credentials = new LinkedList<>();
+        String password = inputData.getFirst(CredentialRepresentation.PASSWORD);
+        if (password == null) {
+            if (context.getUser() != null) {
+                context.getEvent().user(context.getUser());
+            }
+            context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
+            Response challengeResponse = invalidCredentials(context);
+            context.failureChallenge(AuthenticationProcessor.Error.INVALID_CREDENTIALS, challengeResponse);
+            return false;
+        }
+        credentials.add(UserCredentialModel.password(password));
+        boolean valid = context.getSession().users().validCredentials(context.getRealm(), context.getUser(), credentials);
+        if (!valid) {
+            context.getEvent().user(context.getUser());
+            context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
+            Response challengeResponse = invalidCredentials(context);
+            context.failureChallenge(AuthenticationProcessor.Error.INVALID_CREDENTIALS, challengeResponse);
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/CookieAuthenticatorFactory.java b/services/src/main/java/org/keycloak/authentication/authenticators/CookieAuthenticatorFactory.java
index 525fb0b..fc670d4 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/CookieAuthenticatorFactory.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/CookieAuthenticatorFactory.java
@@ -67,13 +67,8 @@ public class CookieAuthenticatorFactory implements AuthenticatorFactory {
     }
 
     @Override
-    public String getDisplayCategory() {
-        return "Complete Authenticator";
-    }
-
-    @Override
     public String getDisplayType() {
-        return "Cookie Authenticator";
+        return "Cookie";
     }
 
     @Override
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/OTPFormAuthenticatorFactory.java b/services/src/main/java/org/keycloak/authentication/authenticators/OTPFormAuthenticatorFactory.java
index f197217..6c8850d 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/OTPFormAuthenticatorFactory.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/OTPFormAuthenticatorFactory.java
@@ -69,10 +69,6 @@ public class OTPFormAuthenticatorFactory implements AuthenticatorFactory {
     public AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
         return REQUIREMENT_CHOICES;
     }
-    @Override
-    public String getDisplayCategory() {
-        return "Credential Validation";
-    }
 
     @Override
     public String getDisplayType() {
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/SpnegoAuthenticatorFactory.java b/services/src/main/java/org/keycloak/authentication/authenticators/SpnegoAuthenticatorFactory.java
index 21c56fc..392ad4a 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/SpnegoAuthenticatorFactory.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/SpnegoAuthenticatorFactory.java
@@ -72,11 +72,6 @@ public class SpnegoAuthenticatorFactory implements AuthenticatorFactory {
     }
 
     @Override
-    public String getDisplayCategory() {
-        return "Complete Authenticator";
-    }
-
-    @Override
     public String getDisplayType() {
         return "SPNEGO";
     }
diff --git a/services/src/main/java/org/keycloak/authentication/AuthenticatorUtil.java b/services/src/main/java/org/keycloak/authentication/AuthenticatorUtil.java
index fcf34ba..30c123e 100755
--- a/services/src/main/java/org/keycloak/authentication/AuthenticatorUtil.java
+++ b/services/src/main/java/org/keycloak/authentication/AuthenticatorUtil.java
@@ -1,14 +1,8 @@
 package org.keycloak.authentication;
 
-import org.keycloak.authentication.authenticators.LoginFormPasswordAuthenticatorFactory;
-import org.keycloak.authentication.authenticators.OTPFormAuthenticatorFactory;
-import org.keycloak.authentication.authenticators.SpnegoAuthenticatorFactory;
 import org.keycloak.models.AuthenticationExecutionModel;
-import org.keycloak.models.AuthenticationFlowModel;
 import org.keycloak.models.AuthenticatorModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.utils.DefaultAuthenticationFlows;
-import org.keycloak.representations.idm.CredentialRepresentation;
 
 import java.util.LinkedList;
 import java.util.List;
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index 1a3bba4..3bec193 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -29,7 +29,7 @@ import org.keycloak.authentication.AuthenticatorUtil;
 import org.keycloak.authentication.RequiredActionContext;
 import org.keycloak.authentication.RequiredActionProvider;
 import org.keycloak.authentication.authenticators.AbstractFormAuthenticator;
-import org.keycloak.authentication.authenticators.LoginFormPasswordAuthenticatorFactory;
+import org.keycloak.authentication.authenticators.UsernamePasswordFormFactory;
 import org.keycloak.email.EmailException;
 import org.keycloak.email.EmailProvider;
 import org.keycloak.events.Details;
@@ -125,23 +125,13 @@ public class LoginActionsService {
     }
 
     public static UriBuilder authenticationFormProcessor(UriInfo uriInfo) {
-        return loginActionsBaseUrl(uriInfo).path(LoginActionsService.class, "authForm");
+        return loginActionsBaseUrl(uriInfo).path(LoginActionsService.class, "authenticateForm");
     }
 
     public static UriBuilder loginActionsBaseUrl(UriBuilder baseUriBuilder) {
         return baseUriBuilder.path(RealmsResource.class).path(RealmsResource.class, "getLoginActionsService");
     }
 
-    public static UriBuilder processOAuthUrl(UriInfo uriInfo) {
-        UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
-        return processOAuthUrl(baseUriBuilder);
-    }
-
-    public static UriBuilder processOAuthUrl(UriBuilder baseUriBuilder) {
-        UriBuilder uriBuilder = loginActionsBaseUrl(baseUriBuilder);
-        return uriBuilder.path(OIDCLoginProtocolService.class, "processOAuth");
-    }
-
     public LoginActionsService(RealmModel realm, AuthenticationManager authManager, EventBuilder event) {
         this.realm = realm;
         this.authManager = authManager;
@@ -241,9 +231,10 @@ public class LoginActionsService {
      * @param code
      * @return
      */
-    @Path("login")
+    @Path("authenticate")
     @GET
-    public Response loginPage(@QueryParam("code") String code) {
+    public Response authenticate(@QueryParam("code") String code,
+                                 @QueryParam("action") String action) {
         event.event(EventType.LOGIN);
         Checks checks = new Checks();
         if (!checks.check(code)) {
@@ -266,6 +257,7 @@ public class LoginActionsService {
                 .setConnection(clientConnection)
                 .setEventBuilder(event)
                 .setProtector(authManager.getProtector())
+                .setAction(action)
                 .setRealm(realm)
                 .setSession(session)
                 .setUriInfo(uriInfo)
@@ -316,10 +308,10 @@ public class LoginActionsService {
      * @param code
      * @return
      */
-    @Path("auth-form")
+    @Path("authenticate")
     @POST
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response authForm(@QueryParam("code") String code,
+    public Response authenticateForm(@QueryParam("code") String code,
                              @QueryParam("action") String action) {
         event.event(EventType.LOGIN);
         Checks checks = new Checks();
@@ -523,7 +515,7 @@ public class LoginActionsService {
 
     public boolean isPasswordRequired() {
         AuthenticationFlowModel browserFlow = realm.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW);
-        return AuthenticatorUtil.isRequired(realm, browserFlow.getId(), LoginFormPasswordAuthenticatorFactory.PROVIDER_ID);
+        return AuthenticatorUtil.isRequired(realm, browserFlow.getId(), UsernamePasswordFormFactory.PROVIDER_ID);
     }
 
     /**
diff --git a/services/src/main/java/org/keycloak/services/Urls.java b/services/src/main/java/org/keycloak/services/Urls.java
index 2adbd1e..2934375 100755
--- a/services/src/main/java/org/keycloak/services/Urls.java
+++ b/services/src/main/java/org/keycloak/services/Urls.java
@@ -176,12 +176,8 @@ public class Urls {
         return UriBuilder.fromUri(baseUri).path(RealmsResource.class);
     }
 
-    public static URI realmLoginAction(URI baseUri, String realmId) {
-        return loginActionsBase(baseUri).path(LoginActionsService.class, "processLogin").build(realmId);
-    }
-
     public static URI realmLoginPage(URI baseUri, String realmId) {
-        return loginActionsBase(baseUri).path(LoginActionsService.class, "loginPage").build(realmId);
+        return loginActionsBase(baseUri).path(LoginActionsService.class, "authenticate").build(realmId);
     }
 
     private static UriBuilder realmLogout(URI baseUri) {
diff --git a/services/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory b/services/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory
index eb41e5e..d4d03d0 100755
--- a/services/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory
+++ b/services/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory
@@ -1,6 +1,4 @@
 org.keycloak.authentication.authenticators.CookieAuthenticatorFactory
-org.keycloak.authentication.authenticators.LoginFormOTPAuthenticatorFactory
-org.keycloak.authentication.authenticators.LoginFormPasswordAuthenticatorFactory
-org.keycloak.authentication.authenticators.LoginFormUsernameAuthenticatorFactory
+org.keycloak.authentication.authenticators.UsernamePasswordFormFactory
 org.keycloak.authentication.authenticators.OTPFormAuthenticatorFactory
 org.keycloak.authentication.authenticators.SpnegoAuthenticatorFactory
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/CredentialHelper.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/CredentialHelper.java
index 8ac3a15..fb38f17 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/CredentialHelper.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/CredentialHelper.java
@@ -1,8 +1,8 @@
 package org.keycloak.testsuite.utils;
 
-import org.keycloak.authentication.authenticators.LoginFormPasswordAuthenticatorFactory;
 import org.keycloak.authentication.authenticators.OTPFormAuthenticatorFactory;
 import org.keycloak.authentication.authenticators.SpnegoAuthenticatorFactory;
+import org.keycloak.authentication.authenticators.UsernamePasswordFormFactory;
 import org.keycloak.models.AuthenticationExecutionModel;
 import org.keycloak.models.AuthenticationFlowModel;
 import org.keycloak.models.AuthenticatorModel;
@@ -36,7 +36,7 @@ public class CredentialHelper {
             String flowAlias = DefaultAuthenticationFlows.BROWSER_FLOW;
             authenticationRequirement(realm, providerId, flowAlias, requirement);
         } else if (type.equals(CredentialRepresentation.PASSWORD)) {
-            String providerId = LoginFormPasswordAuthenticatorFactory.PROVIDER_ID;
+            String providerId = UsernamePasswordFormFactory.PROVIDER_ID;
             String flowAlias = DefaultAuthenticationFlows.FORMS_FLOW;
             authenticationRequirement(realm, providerId, flowAlias, requirement);
         }