Details
diff --git a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
index 1508746..fbe37b4 100755
--- a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
+++ b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
@@ -596,9 +596,8 @@ public class AuthenticationProcessor {
}
public void validateUser(UserModel authenticatedUser) {
- if (authenticatedUser != null) {
- if (!authenticatedUser.isEnabled()) throw new AuthException(Error.USER_DISABLED);
- }
+ if (authenticatedUser == null) return;
+ if (!authenticatedUser.isEnabled()) throw new AuthException(Error.USER_DISABLED);
if (realm.isBruteForceProtected()) {
if (protector.isTemporarilyDisabled(session, realm, authenticatedUser.getUsername())) {
throw new AuthException(Error.USER_TEMPORARILY_DISABLED);
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index c9ca6de..ea95c14 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -592,121 +592,6 @@ public class AuthenticationManager {
return null;
}
- public AuthenticationStatus authenticateForm(KeycloakSession session, ClientConnection clientConnection, RealmModel realm, MultivaluedMap<String, String> formData) {
- String username = formData.getFirst(FORM_USERNAME);
- if (username == null) {
- logger.debug("Username not provided");
- return AuthenticationStatus.INVALID_USER;
- }
-
- if (realm.isBruteForceProtected()) {
- if (protector.isTemporarilyDisabled(session, realm, username)) {
- return AuthenticationStatus.ACCOUNT_TEMPORARILY_DISABLED;
- }
- }
-
- AuthenticationStatus status = authenticateInternal(session, realm, formData, username);
- if (realm.isBruteForceProtected()) {
- switch (status) {
- case SUCCESS:
- protector.successfulLogin(realm, username, clientConnection);
- break;
- case FAILED:
- case MISSING_TOTP:
- case MISSING_PASSWORD:
- case INVALID_CREDENTIALS:
- protector.failedLogin(realm, username, clientConnection);
- break;
- case INVALID_USER:
- protector.invalidUser(realm, username, clientConnection);
- break;
- default:
- break;
- }
- }
-
- return status;
- }
-
- protected AuthenticationStatus authenticateInternal(KeycloakSession session, RealmModel realm, MultivaluedMap<String, String> formData, String username) {
- UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, username);
-
- if (user == null) {
- logger.debugv("User {0} not found", username);
- return AuthenticationStatus.INVALID_USER;
- }
-
- Set<String> types = new HashSet<String>();
-
- for (RequiredCredentialModel credential : realm.getRequiredCredentials()) {
- types.add(credential.getType());
- }
-
- if (types.contains(CredentialRepresentation.PASSWORD)) {
- List<UserCredentialModel> credentials = new LinkedList<UserCredentialModel>();
-
- String password = formData.getFirst(CredentialRepresentation.PASSWORD);
- if (password != null) {
- credentials.add(UserCredentialModel.password(password));
- }
-
- String passwordToken = formData.getFirst(CredentialRepresentation.PASSWORD_TOKEN);
- if (passwordToken != null) {
- credentials.add(UserCredentialModel.passwordToken(passwordToken));
- }
-
- String totp = formData.getFirst(CredentialRepresentation.TOTP);
- if (totp != null) {
- credentials.add(UserCredentialModel.totp(totp));
- }
-
- if ((password == null || password.isEmpty()) && (passwordToken == null || passwordToken.isEmpty())) {
- logger.debug("Password not provided");
- return AuthenticationStatus.MISSING_PASSWORD;
- }
-
- logger.debugv("validating password for user: {0}", username);
-
- if (!session.users().validCredentials(realm, user, credentials)) {
- return AuthenticationStatus.INVALID_CREDENTIALS;
- }
-
- if (!user.isEnabled()) {
- return AuthenticationStatus.ACCOUNT_DISABLED;
- }
-
- if (user.isTotp() && totp == null) {
- return AuthenticationStatus.MISSING_TOTP;
- }
-
- if (!user.getRequiredActions().isEmpty()) {
- return AuthenticationStatus.ACTIONS_REQUIRED;
- } else {
- return AuthenticationStatus.SUCCESS;
- }
- } else if (types.contains(CredentialRepresentation.SECRET)) {
- String secret = formData.getFirst(CredentialRepresentation.SECRET);
- if (secret == null) {
- logger.debug("Secret not provided");
- return AuthenticationStatus.MISSING_PASSWORD;
- }
- if (!session.users().validCredentials(realm, user, UserCredentialModel.secret(secret))) {
- return AuthenticationStatus.INVALID_CREDENTIALS;
- }
- if (!user.isEnabled()) {
- return AuthenticationStatus.ACCOUNT_DISABLED;
- }
- if (!user.getRequiredActions().isEmpty()) {
- return AuthenticationStatus.ACTIONS_REQUIRED;
- } else {
- return AuthenticationStatus.SUCCESS;
- }
- } else {
- logger.warn("Do not know how to authenticate user");
- return AuthenticationStatus.FAILED;
- }
- }
-
public enum AuthenticationStatus {
SUCCESS, ACCOUNT_TEMPORARILY_DISABLED, ACCOUNT_DISABLED, ACTIONS_REQUIRED, INVALID_USER, INVALID_CREDENTIALS, MISSING_PASSWORD, MISSING_TOTP, FAILED
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
index 1799a64..745a5a2 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
@@ -138,6 +138,21 @@ public class LoginTest {
}
@Test
+ public void loginMissingPassword() {
+ loginPage.open();
+ loginPage.missingPassword("login-test");
+
+ loginPage.assertCurrent();
+
+ Assert.assertEquals("Invalid username or password.", loginPage.getError());
+
+ events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials")
+ .detail(Details.USERNAME, "login-test")
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
+ }
+
+ @Test
public void loginInvalidPasswordDisabledUser() {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
@@ -215,6 +230,20 @@ public class LoginTest {
}
@Test
+ public void loginMissingUsername() {
+ loginPage.open();
+ loginPage.missingUsername();
+
+ loginPage.assertCurrent();
+
+ Assert.assertEquals("Invalid username or password.", loginPage.getError());
+
+ events.expectLogin().user((String) null).session((String) null).error("user_not_found")
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
+ }
+
+ @Test
public void loginSuccess() {
loginPage.open();
loginPage.login("login-test", "password");
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
index 3ea0915..0374715 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
@@ -122,6 +122,25 @@ public class LoginTotpTest {
}
@Test
+ public void loginWithMissingTotp() throws Exception {
+ loginPage.open();
+ loginPage.login("test-user@localhost", "password");
+
+ loginTotpPage.assertCurrent();
+
+ loginTotpPage.login(null);
+ loginTotpPage.assertCurrent();
+ Assert.assertEquals("Invalid authenticator code.", loginPage.getError());
+
+ //loginPage.assertCurrent(); // Invalid authenticator code.
+ //Assert.assertEquals("Invalid username or password.", loginPage.getError());
+
+ events.expectLogin().error("invalid_user_credentials").session((String) null)
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
+ }
+
+ @Test
public void loginWithTotpSuccess() throws Exception {
loginPage.open();
loginPage.login("test-user@localhost", "password");
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
old mode 100644
new mode 100755
index 2be207c..2ea8b62
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginPage.java
@@ -91,6 +91,19 @@ public class LoginPage extends AbstractPage {
submitButton.click();
}
+ public void missingPassword(String username) {
+ usernameInput.clear();
+ usernameInput.sendKeys(username);
+ passwordInput.clear();
+ submitButton.click();
+
+ }
+ public void missingUsername() {
+ usernameInput.clear();
+ submitButton.click();
+
+ }
+
public String getUsername() {
return usernameInput.getAttribute("value");
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java
old mode 100644
new mode 100755
index e1a934a..b725a16
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginTotpPage.java
@@ -43,7 +43,8 @@ public class LoginTotpPage extends AbstractPage {
private WebElement loginErrorMessage;
public void login(String totp) {
- totpInput.sendKeys(totp);
+ totpInput.clear();
+ if (totp != null) totpInput.sendKeys(totp);
submitButton.click();
}