You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2017/10/04 15:03:19 UTC

ambari git commit: AMBARI-21220. Update Local Authentication process to work with improved user management facility (rlevas)

Repository: ambari
Updated Branches:
  refs/heads/branch-feature-AMBARI-20859 9eb26a0d8 -> e1699b092


AMBARI-21220. Update Local Authentication process to work with improved user management facility (rlevas)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e1699b09
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e1699b09
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e1699b09

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: e1699b09265e54392ec246a17deec5043f76f54a
Parents: 9eb26a0
Author: Robert Levas <rl...@hortonworks.com>
Authored: Wed Oct 4 11:03:06 2017 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Wed Oct 4 11:03:06 2017 -0400

----------------------------------------------------------------------
 ambari-server/docs/configuration/index.md       |   1 +
 .../server/configuration/Configuration.java     |  13 +-
 .../ambari/server/controller/AmbariServer.java  |   7 +-
 .../AccountDisabledException.java               |  27 +++
 .../AmbariAuthenticationEventHandlerImpl.java   |  11 +-
 .../AmbariAuthenticationProvider.java           |  99 +++++++++
 .../AmbariLocalAuthenticationProvider.java      | 111 ++++++++++
 .../authorization/AmbariLocalUserProvider.java  | 122 -----------
 .../server/security/authorization/Users.java    |   2 +-
 .../AbstractAuthenticationProviderTest.java     | 213 +++++++++++++++++++
 .../AmbariLocalAuthenticationProviderTest.java  |  91 ++++++++
 ...ariAuthorizationProviderDisableUserTest.java | 108 ----------
 .../AmbariLocalUserProviderTest.java            | 190 -----------------
 13 files changed, 566 insertions(+), 429 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/docs/configuration/index.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/configuration/index.md b/ambari-server/docs/configuration/index.md
index 395687d..73d6fd0 100644
--- a/ambari-server/docs/configuration/index.md
+++ b/ambari-server/docs/configuration/index.md
@@ -110,6 +110,7 @@ The following are the properties which can be used to configure Ambari.
 | authentication.ldap.username.forceLowercase | Declares whether to force the ldap user name to be lowercase or leave as-is. This is useful when local user names are expected to be lowercase but the LDAP user names are not. |`false` | 
 | authentication.ldap.usernameAttribute | The attribute used for determining the user name, such as `uid`. |`uid` | 
 | authentication.local.max.failures | The maximum number of authentication attempts permitted to a local user. Once the number of failures reaches this limit the user will be locked out. 0 indicates unlimited failures. |`10` | 
+| authentication.local.show.locked.account.messages | Show or hide whether the user account is disabled or locked out, if relevant, when an authentication attempt fails. |`false` | 
 | authorization.ldap.adminGroupMappingRules | A comma-separate list of groups which would give a user administrative access to Ambari when syncing from LDAP. This is only used when `authorization.ldap.groupSearchFilter` is blank.<br/><br/>The following are examples of valid values:<ul><li>`administrators`<li>`Hadoop Admins,Hadoop Admins.*,DC Admins,.*Hadoop Operators`</ul> |`Ambari Administrators` | 
 | authorization.ldap.groupSearchFilter | The DN to use when searching for LDAP groups. | | 
 | auto.group.creation | The auto group creation by Ambari |`false` | 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index 3099bc0..62e8b86 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -2768,11 +2768,16 @@ public class Configuration {
   /**
    * The maximum number of authentication attempts permitted to a local user. Once the number of failures reaches this limit the user will be locked out. 0 indicates unlimited failures
    */
-  @Markdown(
-    description = "The maximum number of authentication attempts permitted to a local user. Once the number of failures reaches this limit the user will be locked out. 0 indicates unlimited failures.")
+  @Markdown(description = "The maximum number of authentication attempts permitted to a local user. Once the number of failures reaches this limit the user will be locked out. 0 indicates unlimited failures.")
   public static final ConfigurationProperty<Integer> MAX_LOCAL_AUTHENTICATION_FAILURES = new ConfigurationProperty<>(
     "authentication.local.max.failures", 10);
 
+  /**
+   * A flag to determine whether locked out messages are to be shown to users, if relevant, when authenticating into Ambari
+   */
+  @Markdown(description = "Show or hide whether the user account is disabled or locked out, if relevant, when an authentication attempt fails.")
+  public static final ConfigurationProperty<String> SHOW_LOCKED_OUT_USER_MESSAGE = new ConfigurationProperty<>(
+    "authentication.local.show.locked.account.messages", "false");
 
   private static final Logger LOG = LoggerFactory.getLogger(
     Configuration.class);
@@ -6206,4 +6211,8 @@ public class Configuration {
   public int getMaxAuthenticationFailures() {
     return Integer.parseInt(getProperty(MAX_LOCAL_AUTHENTICATION_FAILURES));
   }
+
+  public boolean showLockedOutUserMessage() {
+    return Boolean.parseBoolean(getProperty(SHOW_LOCKED_OUT_USER_MESSAGE));
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 21ab757..0d24ef2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -100,8 +100,8 @@ import org.apache.ambari.server.security.AmbariViewsSecurityHeaderFilter;
 import org.apache.ambari.server.security.CertificateManager;
 import org.apache.ambari.server.security.SecurityFilter;
 import org.apache.ambari.server.security.authentication.AmbariAuthenticationEventHandlerImpl;
+import org.apache.ambari.server.security.authentication.AmbariLocalAuthenticationProvider;
 import org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider;
-import org.apache.ambari.server.security.authorization.AmbariLocalUserProvider;
 import org.apache.ambari.server.security.authorization.AmbariPamAuthenticationProvider;
 import org.apache.ambari.server.security.authorization.AmbariUserAuthorizationFilter;
 import org.apache.ambari.server.security.authorization.PermissionHelper;
@@ -339,9 +339,8 @@ public class AmbariServer {
         injector.getInstance(PermissionHelper.class));
       factory.registerSingleton("ambariLdapAuthenticationProvider",
         injector.getInstance(AmbariLdapAuthenticationProvider.class));
-      AmbariLocalUserProvider ambariLocalUserProvider = injector.getInstance(AmbariLocalUserProvider.class);
-      ambariLocalUserProvider.setMaxConsecutiveFailures(configs.getMaxAuthenticationFailures());
-      factory.registerSingleton("ambariLocalAuthenticationProvider", ambariLocalUserProvider);
+      factory.registerSingleton("ambariLocalAuthenticationProvider",
+          injector.getInstance(AmbariLocalAuthenticationProvider.class));
       factory.registerSingleton("ambariLdapDataPopulator",
         injector.getInstance(AmbariLdapDataPopulator.class));
       factory.registerSingleton("ambariUserAuthorizationFilter",

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AccountDisabledException.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AccountDisabledException.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AccountDisabledException.java
new file mode 100644
index 0000000..4a88f46
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AccountDisabledException.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ambari.server.security.authentication;
+
+/**
+ * Thrown when the account has been flagged as inactive
+ */
+public class AccountDisabledException extends AmbariAuthenticationException {
+  public AccountDisabledException(String username) {
+    super(username, "The account is disabled");
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariAuthenticationEventHandlerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariAuthenticationEventHandlerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariAuthenticationEventHandlerImpl.java
index 2a89437..4cfce2a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariAuthenticationEventHandlerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariAuthenticationEventHandlerImpl.java
@@ -106,10 +106,17 @@ public class AmbariAuthenticationEventHandlerImpl implements AmbariAuthenticatio
       message = cause.getLocalizedMessage();
     }
 
-    // Increment the user's consecutive authentication failure count.
     if (!StringUtils.isEmpty(username)) {
+      // Increment the user's consecutive authentication failure count.
       consecutiveFailures = users.incrementConsecutiveAuthenticationFailures(username);
-      logMessage = String.format("Failed to authenticate %s (attempt #%d): %s", username, consecutiveFailures, message);
+
+      // If consecutiveFailures is NULL, then no user entry was found for the specified username.
+      if(consecutiveFailures == null) {
+        logMessage = String.format("Failed to authenticate %s: The user does not exist in the Ambari database", username);
+      }
+      else {
+        logMessage = String.format("Failed to authenticate %s (attempt #%d): %s", username, consecutiveFailures, message);
+      }
     } else {
       logMessage = String.format("Failed to authenticate an unknown user: %s", message);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariAuthenticationProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariAuthenticationProvider.java
new file mode 100644
index 0000000..3d20cb9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariAuthenticationProvider.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ambari.server.security.authentication;
+
+import java.util.Collection;
+
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.orm.entities.UserAuthenticationEntity;
+import org.apache.ambari.server.orm.entities.UserEntity;
+import org.apache.ambari.server.security.authorization.UserAuthenticationType;
+import org.apache.ambari.server.security.authorization.Users;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.AuthenticationProvider;
+
+/**
+ * AmbariAuthenticationProvider is an abstract class to be extended by Ambari authentication providers.
+ * <p>
+ * This class contains common methods that may be used by authentication providers.
+ */
+abstract class AmbariAuthenticationProvider implements AuthenticationProvider {
+  private static final Logger LOG = LoggerFactory.getLogger(AmbariAuthenticationProvider.class);
+
+  private Users users;
+  private Configuration configuration;
+
+  AmbariAuthenticationProvider(Users users, Configuration configuration) {
+    this.users = users;
+    this.configuration = configuration;
+  }
+
+  /**
+   * Gets the {@link UserEntity} for the user with the specified username.
+   * <p>
+   * The entity is validated such that the account is allowed to log in before returning. For example,
+   * if the account is not acitve, no user may not login as that account.
+   *
+   * @param userName
+   * @return
+   */
+  UserEntity getUserEntity(String userName) {
+    LOG.debug("Loading user by name: {}", userName);
+    UserEntity userEntity = users.getUserEntity(userName);
+
+    if (userEntity == null) {
+      LOG.info("User not found: {}", userName);
+      throw new InvalidUsernamePasswordCombinationException(userName);
+    }
+
+    if (!userEntity.getActive()) {
+      LOG.info("User account is disabled: {}", userName);
+      if (configuration.showLockedOutUserMessage()) {
+        throw new AccountDisabledException(userName);
+      } else {
+        throw new InvalidUsernamePasswordCombinationException(userName);
+      }
+    }
+
+    return userEntity;
+  }
+
+  /**
+   * Finds the specific {@link UserAuthenticationEntity} from the collection of authentication methods
+   * available to the specified {@link UserEntity}.
+   *
+   * @param userEntity a {@link UserEntity}
+   * @param type       the {@link UserAuthenticationType} to retrieve
+   * @return a {@link UserAuthenticationEntity} if found; otherwise null
+   */
+  UserAuthenticationEntity getAuthenticationEntity(UserEntity userEntity, UserAuthenticationType type) {
+    Collection<UserAuthenticationEntity> authenticationEntities = (userEntity == null) ? null : userEntity.getAuthenticationEntities();
+    if (authenticationEntities != null) {
+      for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
+        if (authenticationEntity.getAuthenticationType() == type) {
+          return authenticationEntity;
+        }
+      }
+    }
+
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariLocalAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariLocalAuthenticationProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariLocalAuthenticationProvider.java
new file mode 100644
index 0000000..dcdf471
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/AmbariLocalAuthenticationProvider.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ambari.server.security.authentication;
+
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.orm.entities.UserAuthenticationEntity;
+import org.apache.ambari.server.orm.entities.UserEntity;
+import org.apache.ambari.server.security.authorization.AmbariUserAuthentication;
+import org.apache.ambari.server.security.authorization.User;
+import org.apache.ambari.server.security.authorization.UserAuthenticationType;
+import org.apache.ambari.server.security.authorization.Users;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+import com.google.inject.Inject;
+
+/**
+ * AmbariLocalAuthenticationProvider is an {@link org.springframework.security.authentication.AuthenticationProvider}
+ * implementation used to authenticate users using username and password details from the local Ambari database.
+ * <p>
+ * Users will fail to authenticate, even if they supply the correct credentials if the account is locked out
+ * by being disabled or locked due to too many consecutive failure.
+ */
+public class AmbariLocalAuthenticationProvider extends AmbariAuthenticationProvider {
+  private static final Logger LOG = LoggerFactory.getLogger(AmbariLocalAuthenticationProvider.class);
+
+  private Users users;
+  private PasswordEncoder passwordEncoder;
+  private Configuration configuration;
+
+  @Inject
+  public AmbariLocalAuthenticationProvider(Users users, PasswordEncoder passwordEncoder, Configuration configuration) {
+    super(users, configuration);
+    this.users = users;
+    this.passwordEncoder = passwordEncoder;
+    this.configuration = configuration;
+  }
+
+  @Override
+  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+    String userName = authentication.getName().trim();
+
+    UserEntity userEntity = getUserEntity(userName);
+
+    if (userEntity == null) {
+      LOG.info("User not found: {}", userName);
+      throw new InvalidUsernamePasswordCombinationException(userName);
+    }
+
+    int maxConsecutiveFailures = configuration.getMaxAuthenticationFailures();
+    if (maxConsecutiveFailures > 0 && userEntity.getConsecutiveFailures() >= maxConsecutiveFailures) {
+      LOG.info("User account is locked out due to too many authentication failures ({}/{}): {}",
+          userEntity.getConsecutiveFailures(), maxConsecutiveFailures, userName);
+      if (configuration.showLockedOutUserMessage()) {
+        throw new TooManyLoginFailuresException(userName);
+      } else {
+        throw new InvalidUsernamePasswordCombinationException(userName);
+      }
+    }
+
+
+    if (authentication.getCredentials() == null) {
+      LOG.info("Authentication failed: no credentials provided: {}", userName);
+      throw new InvalidUsernamePasswordCombinationException(userName);
+    }
+
+    UserAuthenticationEntity authenticationEntity = getAuthenticationEntity(userEntity, UserAuthenticationType.LOCAL);
+    if (authenticationEntity != null) {
+      String password = authenticationEntity.getAuthenticationKey();
+      String presentedPassword = authentication.getCredentials().toString();
+
+      if (passwordEncoder.matches(presentedPassword, password)) {
+        // The user was  authenticated, return the authenticated user object
+        LOG.debug("Authentication succeeded - a matching username and password were found: {}", userName);
+
+        User user = new User(userEntity);
+        Authentication auth = new AmbariUserAuthentication(password, user, users.getUserAuthorities(userEntity));
+        auth.setAuthenticated(true);
+        return auth;
+      }
+    }
+
+    // The user was not authenticated, fail
+    LOG.debug("Authentication failed: password does not match stored value: {}", userName);
+    throw new InvalidUsernamePasswordCombinationException(userName);
+  }
+
+  @Override
+  public boolean supports(Class<?> authentication) {
+    return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLocalUserProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLocalUserProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLocalUserProvider.java
deleted file mode 100644
index 2a2e397..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLocalUserProvider.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.ambari.server.security.authorization;
-
-import java.util.List;
-
-import org.apache.ambari.server.orm.dao.UserDAO;
-import org.apache.ambari.server.orm.entities.UserAuthenticationEntity;
-import org.apache.ambari.server.orm.entities.UserEntity;
-import org.apache.ambari.server.security.authentication.InvalidUsernamePasswordCombinationException;
-import org.apache.ambari.server.security.authentication.TooManyLoginFailuresException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.crypto.password.PasswordEncoder;
-
-import com.google.inject.Inject;
-
-public class AmbariLocalUserProvider extends AbstractUserDetailsAuthenticationProvider {
-  private static final Logger LOG = LoggerFactory.getLogger(AmbariLocalUserProvider.class);
-  private UserDAO userDAO;
-  private Users users;
-  private PasswordEncoder passwordEncoder;
-  private int maxConsecutiveFailures = 0;
-
-  @Inject
-  public AmbariLocalUserProvider(UserDAO userDAO, Users users, PasswordEncoder passwordEncoder) {
-    this.userDAO = userDAO;
-    this.users = users;
-    this.passwordEncoder = passwordEncoder;
-  }
-
-  @Override
-  protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
-    // do nothing
-  }
-
-  // TODO: ************
-  // TODO: This is to be revisited for AMBARI-21220 (Update Local Authentication process to work with improved user management facility)
-  // TODO: ************
-  @Override
-  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
-    String userName = authentication.getName().trim();
-
-    LOG.info("Loading user by name: " + userName);
-
-    UserEntity userEntity = userDAO.findUserByName(userName);
-
-    if (userEntity == null) {
-      LOG.info("user not found");
-      throw new InvalidUsernamePasswordCombinationException(userName);
-    }
-
-    if (!userEntity.getActive()) {
-      LOG.debug("User account is disabled");
-      throw new InvalidUsernamePasswordCombinationException(userName);
-    }
-
-    if (maxConsecutiveFailures > 0 && userEntity.getConsecutiveFailures() >= maxConsecutiveFailures) {
-      throw new TooManyLoginFailuresException(userName);
-    }
-
-    if (authentication.getCredentials() == null) {
-      LOG.debug("Authentication failed: no credentials provided");
-      throw new InvalidUsernamePasswordCombinationException(userName);
-    }
-
-    List<UserAuthenticationEntity> authenticationEntities = userEntity.getAuthenticationEntities();
-    for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
-      if (authenticationEntity.getAuthenticationType() == UserAuthenticationType.LOCAL) {
-        // This should only get invoked once...
-        String password = authenticationEntity.getAuthenticationKey();
-        String presentedPassword = authentication.getCredentials().toString();
-
-        if (passwordEncoder.matches(presentedPassword, password)) {
-          // The user was  authenticated, return the authenticated user object
-          User user = new User(userEntity);
-          Authentication auth = new AmbariUserAuthentication(password, user, users.getUserAuthorities(userEntity));
-          auth.setAuthenticated(true);
-          return auth;
-        }
-      }
-    }
-
-    // The user was not authenticated, fail
-    LOG.debug("Authentication failed: password does not match stored value");
-    throw new InvalidUsernamePasswordCombinationException(userName);
-  }
-
-  @Override
-  protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
-    return null;
-  }
-
-  @Override
-  public boolean supports(Class<?> authentication) {
-    return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
-  }
-
-  public void setMaxConsecutiveFailures(int maxConsecutiveFailures) {
-    this.maxConsecutiveFailures = maxConsecutiveFailures;
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
index 2dedc9e..a5faea1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
@@ -1281,7 +1281,6 @@ public class Users {
   }
 
   /**
-   * TODO: This is to be revisited for AMBARI-21220 (Update Local Authentication process to work with improved user management facility)
    * Adds the ability for a user to authenticate using a password stored in Ambari's database
    * <p>
    * The supplied plaintext password will be encoded before storing.
@@ -1292,6 +1291,7 @@ public class Users {
    */
   public void addLocalAuthentication(UserEntity userEntity, String password) throws AmbariException {
 
+    // Ensure the password meets configured minimal requirements, if any
     validatePassword(password);
 
     // Encode the password..

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/AbstractAuthenticationProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/AbstractAuthenticationProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/AbstractAuthenticationProviderTest.java
new file mode 100644
index 0000000..96b4883
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/AbstractAuthenticationProviderTest.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ambari.server.security.authentication;
+
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.expect;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import javax.persistence.EntityManager;
+
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.hooks.HookContextFactory;
+import org.apache.ambari.server.hooks.HookService;
+import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.orm.entities.UserEntity;
+import org.apache.ambari.server.security.authorization.AmbariUserAuthentication;
+import org.apache.ambari.server.security.authorization.Users;
+import org.apache.ambari.server.state.stack.OsFamily;
+import org.easymock.EasyMockSupport;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
+abstract class AbstractAuthenticationProviderTest extends EasyMockSupport {
+
+  static final String TEST_USER_NAME = "userName";
+
+  @Before
+  public void setUp() throws Exception {
+    SecurityContextHolder.getContext().setAuthentication(null);
+  }
+
+  @After
+  public void cleanUp() throws Exception {
+    SecurityContextHolder.getContext().setAuthentication(null);
+  }
+
+
+  @Test
+  public void testAuthenticationSuccess() {
+    Injector injector = getInjector();
+
+    UserEntity userEntity = getUserEntity(injector, TEST_USER_NAME, 9, true);
+
+    Users users = injector.getInstance(Users.class);
+    expect(users.getUserEntity(TEST_USER_NAME)).andReturn(userEntity).atLeastOnce();
+    expect(users.getUserAuthorities(userEntity)).andReturn(null).atLeastOnce();
+
+    Authentication authentication = getAuthentication(true, true);
+
+    replayAll();
+
+    AuthenticationProvider provider = getAuthenticationProvider(injector);
+    Authentication result = provider.authenticate(authentication);
+
+    verifyAll();
+
+    assertNotNull(result);
+    assertEquals(true, result.isAuthenticated());
+    assertTrue(result instanceof AmbariUserAuthentication);
+
+    validateAuthenticationResult((AmbariUserAuthentication) result);
+  }
+
+  @Test(expected = AmbariAuthenticationException.class)
+  public void testAuthenticationWithIncorrectUserName() {
+    Injector injector = getInjector();
+
+    Authentication authentication = getAuthentication(false, true);
+
+    Users users = injector.getInstance(Users.class);
+    expect(users.getUserEntity(anyString())).andReturn(null).atLeastOnce();
+
+    replayAll();
+
+    AuthenticationProvider provider = getAuthenticationProvider(injector);
+    provider.authenticate(authentication);
+  }
+
+
+  @Test(expected = AmbariAuthenticationException.class)
+  public void testAuthenticationWithoutCredentials() {
+    Injector injector = getInjector();
+
+    UserEntity userEntity = getUserEntity(injector, TEST_USER_NAME, 0, true);
+
+    Users users = injector.getInstance(Users.class);
+    expect(users.getUserEntity(TEST_USER_NAME)).andReturn(userEntity).atLeastOnce();
+    expect(users.getUserAuthorities(userEntity)).andReturn(null).atLeastOnce();
+
+    Authentication authentication = createMock(Authentication.class);
+    expect(authentication.getName()).andReturn(TEST_USER_NAME).atLeastOnce();
+    expect(authentication.getCredentials()).andReturn(null).atLeastOnce();
+
+    replayAll();
+
+    AuthenticationProvider provider = getAuthenticationProvider(injector);
+    provider.authenticate(authentication);
+  }
+
+
+  @Test(expected = AmbariAuthenticationException.class)
+  public void testAuthenticationWithIncorrectCredential() {
+    Injector injector = getInjector();
+
+    UserEntity userEntity = getUserEntity(injector, TEST_USER_NAME, 0, true);
+
+    Users users = injector.getInstance(Users.class);
+    expect(users.getUserEntity(TEST_USER_NAME)).andReturn(userEntity).atLeastOnce();
+    expect(users.getUserAuthorities(userEntity)).andReturn(null).atLeastOnce();
+
+    Authentication authentication = getAuthentication(true, false);
+
+    replayAll();
+
+    AuthenticationProvider provider = getAuthenticationProvider(injector);
+    provider.authenticate(authentication);
+  }
+
+  @Test(expected = TooManyLoginFailuresException.class)
+  public void testUserIsLockedOutAfterConsecutiveFailures() {
+    Injector injector = getInjector();
+
+    // Force the user to have more than 10 consecutive failures
+    UserEntity userEntity = getUserEntity(injector, TEST_USER_NAME, 11, true);
+
+    Users users = injector.getInstance(Users.class);
+    expect(users.getUserEntity(TEST_USER_NAME)).andReturn(userEntity).atLeastOnce();
+
+    Authentication authentication = getAuthentication(true, true);
+
+    replayAll();
+
+    AmbariLocalAuthenticationProvider ambariLocalAuthenticationProvider = injector.getInstance(AmbariLocalAuthenticationProvider.class);
+    ambariLocalAuthenticationProvider.authenticate(authentication);
+  }
+
+  @Test(expected = AccountDisabledException.class)
+  public void testUserIsInactive() {
+    Injector injector = getInjector();
+
+    // Force the user to be inactive
+    UserEntity userEntity = getUserEntity(injector, TEST_USER_NAME, 10, false);
+
+    Users users = injector.getInstance(Users.class);
+    expect(users.getUserEntity(TEST_USER_NAME)).andReturn(userEntity).atLeastOnce();
+
+    Authentication authentication = getAuthentication(true, true);
+
+    replayAll();
+
+    AmbariLocalAuthenticationProvider ambariLocalAuthenticationProvider = injector.getInstance(AmbariLocalAuthenticationProvider.class);
+    ambariLocalAuthenticationProvider.authenticate(authentication);
+  }
+
+  protected Injector getInjector() {
+    return Guice.createInjector(new AbstractModule() {
+      @Override
+      protected void configure() {
+        Configuration configuration = createNiceMock(Configuration.class);
+        expect(configuration.getMaxAuthenticationFailures()).andReturn(10).anyTimes();
+        expect(configuration.showLockedOutUserMessage()).andReturn(true).anyTimes();
+
+        bind(EntityManager.class).toInstance(createMock(EntityManager.class));
+        bind(DBAccessor.class).toInstance(createMock(DBAccessor.class));
+        bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+        bind(HookService.class).toInstance(createMock(HookService.class));
+        bind(HookContextFactory.class).toInstance(createMock(HookContextFactory.class));
+
+        bind(Users.class).toInstance(createMock(Users.class));
+        bind(Configuration.class).toInstance(configuration);
+      }
+    }, getAdditionalModule());
+
+  }
+
+  protected abstract AuthenticationProvider getAuthenticationProvider(Injector injector);
+
+  protected abstract Authentication getAuthentication(boolean correctUsername, boolean correctCredential);
+
+  protected abstract UserEntity getUserEntity(Injector injector, String username, int consecutiveFailures, boolean active);
+
+  protected abstract Module getAdditionalModule();
+
+  protected abstract void validateAuthenticationResult(AmbariUserAuthentication result);
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/AmbariLocalAuthenticationProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/AmbariLocalAuthenticationProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/AmbariLocalAuthenticationProviderTest.java
new file mode 100644
index 0000000..d445c07
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/AmbariLocalAuthenticationProviderTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ambari.server.security.authentication;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collections;
+
+import org.apache.ambari.server.orm.entities.PrincipalEntity;
+import org.apache.ambari.server.orm.entities.UserAuthenticationEntity;
+import org.apache.ambari.server.orm.entities.UserEntity;
+import org.apache.ambari.server.security.authorization.AmbariUserAuthentication;
+import org.apache.ambari.server.security.authorization.UserAuthenticationType;
+import org.apache.ambari.server.security.authorization.UserName;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.crypto.password.StandardPasswordEncoder;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
+public class AmbariLocalAuthenticationProviderTest extends AbstractAuthenticationProviderTest {
+
+  private static final String TEST_USER_PASS = "userPass";
+  private static final String TEST_USER_INCORRECT_PASS = "userIncorrectPass";
+
+  @Override
+  protected AuthenticationProvider getAuthenticationProvider(Injector injector) {
+    return injector.getInstance(AmbariLocalAuthenticationProvider.class);
+  }
+
+  @Override
+  protected Authentication getAuthentication(boolean correctUsername, boolean correctCredential) {
+    return new UsernamePasswordAuthenticationToken(
+        correctUsername ? TEST_USER_NAME : "incorrect_username",
+        correctCredential ? TEST_USER_PASS : TEST_USER_INCORRECT_PASS
+    );
+  }
+
+  @Override
+  protected UserEntity getUserEntity(Injector injector, String username, int consecutiveFailures, boolean active) {
+    PrincipalEntity principalEntity = new PrincipalEntity();
+
+    UserAuthenticationEntity userAuthenticationEntity = new UserAuthenticationEntity();
+    userAuthenticationEntity.setAuthenticationType(UserAuthenticationType.LOCAL);
+    userAuthenticationEntity.setAuthenticationKey(injector.getInstance(PasswordEncoder.class).encode(TEST_USER_PASS));
+
+    UserEntity userEntity = new UserEntity();
+    userEntity.setUserId(1);
+    userEntity.setUserName(UserName.fromString(username).toString());
+    userEntity.setPrincipal(principalEntity);
+    userEntity.setAuthenticationEntities(Collections.singletonList(userAuthenticationEntity));
+    userEntity.setConsecutiveFailures(consecutiveFailures);
+    userEntity.setActive(active);
+    return userEntity;
+  }
+
+  @Override
+  protected Module getAdditionalModule() {
+    return new AbstractModule() {
+      @Override
+      protected void configure() {
+        bind(PasswordEncoder.class).toInstance(new StandardPasswordEncoder());
+      }
+    };
+  }
+
+  @Override
+  protected void validateAuthenticationResult(AmbariUserAuthentication result) {
+    assertEquals(1, (result.getPrincipal()).getUserId());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationProviderDisableUserTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationProviderDisableUserTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationProviderDisableUserTest.java
deleted file mode 100644
index fea7fb9..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationProviderDisableUserTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.ambari.server.security.authorization;
-
-import java.util.Collections;
-
-import org.apache.ambari.server.orm.dao.MemberDAO;
-import org.apache.ambari.server.orm.dao.PrivilegeDAO;
-import org.apache.ambari.server.orm.dao.UserDAO;
-import org.apache.ambari.server.orm.entities.PrincipalEntity;
-import org.apache.ambari.server.orm.entities.UserAuthenticationEntity;
-import org.apache.ambari.server.orm.entities.UserEntity;
-import org.apache.ambari.server.security.authentication.InvalidUsernamePasswordCombinationException;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.crypto.password.StandardPasswordEncoder;
-
-public class AmbariAuthorizationProviderDisableUserTest {
-
-  private Users users;
-
-  private UserDAO userDAO;
-  
-  private PasswordEncoder encoder = new StandardPasswordEncoder();
-
-  private AmbariLocalUserProvider alup;
-
-  private AmbariLdapAuthoritiesPopulator ldapPopulator;
-
-  @Before
-  public void setUp() {
-    userDAO = Mockito.mock(UserDAO.class);
-    users = Mockito.mock(Users.class);
-
-    createUser("activeUser", true);
-    createUser("disabledUser", false);
-    
-    MemberDAO memberDao = Mockito.mock(MemberDAO.class);
-    PrivilegeDAO privilegeDao = Mockito.mock(PrivilegeDAO.class);
-    AuthorizationHelper authorizationHelper = new AuthorizationHelper();
-
-    alup = new AmbariLocalUserProvider(userDAO, users, encoder);
-    
-    ldapPopulator = new AmbariLdapAuthoritiesPopulator(authorizationHelper, userDAO, memberDao, privilegeDao, users);
-    
-  }
-  
-  @Test public void testDisabledUserViaDaoProvider(){
-    try {
-      alup.authenticate(new UsernamePasswordAuthenticationToken("disabledUser","pwd"));
-      Assert.fail("Disabled user passes authentication");
-    } catch (InvalidUsernamePasswordCombinationException e){
-      //expected
-      Assert.assertEquals(InvalidUsernamePasswordCombinationException.MESSAGE, e.getMessage());//UI depends on this
-    }
-    Authentication auth = alup.authenticate(new UsernamePasswordAuthenticationToken("activeUser","pwd"));
-    Assert.assertNotNull(auth);
-    Assert.assertTrue(auth.isAuthenticated());
-  }
-
-  @Test public void testDisabledUserViaLdapProvider(){
-    try {
-      ldapPopulator.getGrantedAuthorities(null, "disabledUser");
-      Assert.fail("Disabled user passes authentication");
-    } catch (InvalidUsernamePasswordCombinationException e) {
-      //expected
-      Assert.assertEquals(InvalidUsernamePasswordCombinationException.MESSAGE, e.getMessage());//UI depends on this
-    }
-  }
-  
-  private void createUser(String login, boolean isActive) {
-    PrincipalEntity principalEntity = new PrincipalEntity();
-
-    UserAuthenticationEntity userAuthenticationEntity = new UserAuthenticationEntity();
-    userAuthenticationEntity.setAuthenticationType(UserAuthenticationType.LOCAL);
-    userAuthenticationEntity.setAuthenticationKey(encoder.encode("pwd"));
-
-    UserEntity activeUser = new UserEntity();
-    activeUser.setUserId(1);
-    activeUser.setActive(isActive);
-    activeUser.setUserName(UserName.fromString(login).toString());
-    activeUser.setAuthenticationEntities(Collections.singletonList(userAuthenticationEntity));
-    activeUser.setPrincipal(principalEntity);
-    Mockito.when(userDAO.findUserByName(login)).thenReturn(activeUser);
-    Mockito.when(userDAO.findUserByName(login)).thenReturn(activeUser);
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/e1699b09/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLocalUserProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLocalUserProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLocalUserProviderTest.java
deleted file mode 100644
index fb4ebf9..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLocalUserProviderTest.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.ambari.server.security.authorization;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Collections;
-
-import org.apache.ambari.server.H2DatabaseCleaner;
-import org.apache.ambari.server.audit.AuditLoggerModule;
-import org.apache.ambari.server.orm.GuiceJpaInitializer;
-import org.apache.ambari.server.orm.OrmTestHelper;
-import org.apache.ambari.server.orm.dao.UserDAO;
-import org.apache.ambari.server.orm.entities.PrincipalEntity;
-import org.apache.ambari.server.orm.entities.UserAuthenticationEntity;
-import org.apache.ambari.server.orm.entities.UserEntity;
-import org.apache.ambari.server.security.authentication.InvalidUsernamePasswordCombinationException;
-import org.apache.ambari.server.security.authentication.TooManyLoginFailuresException;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-
-import com.google.inject.Guice;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-
-public class AmbariLocalUserProviderTest {
-  private static Injector injector;
-
-  @Inject
-  PasswordEncoder passwordEncoder;
-
-  private static final String TEST_USER_NAME = "userName";
-  private static final String TEST_USER_PASS = "userPass";
-  private static final String TEST_USER_INCORRECT_PASS = "userIncorrectPass";
-
-  @BeforeClass
-  public static void prepareData() {
-    injector = Guice.createInjector(new AuditLoggerModule(), new AuthorizationTestModule());
-    injector.getInstance(GuiceJpaInitializer.class);
-    injector.getInstance(OrmTestHelper.class).createTestUsers();
-  }
-
-  @Before
-  public void setUp() throws Exception {
-    injector.injectMembers(this);
-    SecurityContextHolder.getContext().setAuthentication(null);
-  }
-
-  @AfterClass
-  public static void tearDown() throws Exception {
-    H2DatabaseCleaner.clearDatabaseAndStopPersistenceService(injector);
-  }
-
-  @Test
-  public void testSuccessfulAuth() {
-    Users users = createMock(Users.class);
-    UserDAO userDAO = createMock(UserDAO.class);
-    Authentication authentication = createMock(Authentication.class);
-
-    UserEntity userEntity = combineUserEntity();
-
-    expect(authentication.getName()).andReturn(TEST_USER_NAME);
-    expect(userDAO.findUserByName(TEST_USER_NAME)).andReturn(userEntity);
-    expect(authentication.getCredentials()).andReturn(TEST_USER_PASS).anyTimes();
-    expect(users.getUserAuthorities(userEntity)).andReturn(null);
-
-    replay(users, userDAO, authentication);
-
-    AmbariLocalUserProvider ambariLocalUserProvider = new AmbariLocalUserProvider(userDAO, users, passwordEncoder);
-    Authentication resultedAuth = ambariLocalUserProvider.authenticate(authentication);
-
-    verify(users, userDAO, authentication);
-
-    assertNotNull(resultedAuth);
-    assertEquals(true, resultedAuth.isAuthenticated());
-    assertTrue(resultedAuth instanceof AmbariUserAuthentication);
-    assertEquals(1, ((User) resultedAuth.getPrincipal()).getUserId());
-  }
-
-  @Test(expected = InvalidUsernamePasswordCombinationException.class)
-  public void testAuthWithIncorrectName() {
-    Users users = createMock(Users.class);
-    UserDAO userDAO = createMock(UserDAO.class);
-    Authentication authentication = createMock(Authentication.class);
-
-    expect(authentication.getName()).andReturn(TEST_USER_NAME);
-    expect(userDAO.findUserByName(TEST_USER_NAME)).andReturn(null);
-
-    replay(users, userDAO, authentication);
-
-    AmbariLocalUserProvider ambariLocalUserProvider = new AmbariLocalUserProvider(userDAO, users, passwordEncoder);
-    ambariLocalUserProvider.authenticate(authentication);
-  }
-
-  @Test(expected = InvalidUsernamePasswordCombinationException.class)
-  public void testAuthWithoutPass() {
-    Users users = createMock(Users.class);
-    UserDAO userDAO = createMock(UserDAO.class);
-    Authentication authentication = createMock(Authentication.class);
-
-    UserEntity userEntity = combineUserEntity();
-
-    expect(authentication.getName()).andReturn(TEST_USER_NAME);
-    expect(userDAO.findUserByName(TEST_USER_NAME)).andReturn(userEntity);
-    expect(authentication.getCredentials()).andReturn(null);
-
-    replay(users, userDAO, authentication);
-
-    AmbariLocalUserProvider ambariLocalUserProvider = new AmbariLocalUserProvider(userDAO, users, passwordEncoder);
-    ambariLocalUserProvider.authenticate(authentication);
-  }
-
-  @Test(expected = InvalidUsernamePasswordCombinationException.class)
-  public void testAuthWithIncorrectPass() {
-    Users users = createMock(Users.class);
-    UserDAO userDAO = createMock(UserDAO.class);
-    Authentication authentication = createMock(Authentication.class);
-
-    UserEntity userEntity = combineUserEntity();
-
-    expect(authentication.getName()).andReturn(TEST_USER_NAME);
-    expect(userDAO.findUserByName(TEST_USER_NAME)).andReturn(userEntity);
-    expect(authentication.getCredentials()).andReturn(TEST_USER_INCORRECT_PASS).anyTimes();
-
-    replay(users, userDAO, authentication);
-
-    AmbariLocalUserProvider ambariLocalUserProvider = new AmbariLocalUserProvider(userDAO, users, passwordEncoder);
-    ambariLocalUserProvider.authenticate(authentication);
-  }
-
-  @Test(expected = TooManyLoginFailuresException.class)
-  public void testUserIsLockedOutAfterConsecutiveFailures() {
-    Users users = createMock(Users.class);
-    UserDAO userDAO = createMock(UserDAO.class);
-    Authentication authentication = createMock(Authentication.class);
-
-    UserEntity userEntity = combineUserEntity();
-    userEntity.setConsecutiveFailures(3);
-    expect(authentication.getName()).andReturn(TEST_USER_NAME).anyTimes();
-    expect(authentication.getCredentials()).andReturn(TEST_USER_PASS).anyTimes();
-    expect(userDAO.findUserByName(TEST_USER_NAME)).andReturn(userEntity).anyTimes();
-    expect(users.getUserAuthorities(userEntity)).andReturn(null);
-
-    replay(users, userDAO, authentication);
-    AmbariLocalUserProvider ambariLocalUserProvider = new AmbariLocalUserProvider(userDAO, users, passwordEncoder);
-    ambariLocalUserProvider.setMaxConsecutiveFailures(3);
-    ambariLocalUserProvider.authenticate(authentication);
-  }
-
-  private UserEntity combineUserEntity() {
-    PrincipalEntity principalEntity = new PrincipalEntity();
-
-    UserAuthenticationEntity userAuthenticationEntity = new UserAuthenticationEntity();
-    userAuthenticationEntity.setAuthenticationType(UserAuthenticationType.LOCAL);
-    userAuthenticationEntity.setAuthenticationKey(passwordEncoder.encode(TEST_USER_PASS));
-
-    UserEntity userEntity = new UserEntity();
-    userEntity.setUserId(1);
-    userEntity.setUserName(UserName.fromString(TEST_USER_NAME).toString());
-    userEntity.setPrincipal(principalEntity);
-    userEntity.setAuthenticationEntities(Collections.singletonList(userAuthenticationEntity));
-    return userEntity;
-  }
-}