class AmbariLdapAuthenticationProvider extends AmbariAuthenticationProvider {

  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    if (isLdapEnabled()) {
      if (authentication.getName() == null) {
        LOG.info("Authentication failed: no username provided");
        throw new InvalidUsernamePasswordCombinationException("");
      }

      String username = authentication.getName().trim();

      if (authentication.getCredentials() == null) {
        LOG.info("Authentication failed: no credentials provided: {}", username);
        throw new InvalidUsernamePasswordCombinationException(username);
      }

      try {
        Authentication auth = loadLdapAuthenticationProvider(username).authenticate(authentication);
        UserEntity userEntity = getUserEntity(auth);

        if (userEntity == null) {
          // TODO: If we were automatically importing accounts from the LDAP server, we should
          // TODO: probably do it here.
          LOG.debug("user not found ('{}')", username);
          throw new InvalidUsernamePasswordCombinationException(username);
        } else {
          Users users = getUsers();

          // Ensure the user is allowed to login....
          try {
            users.validateLogin(userEntity, username);
          } catch (AccountDisabledException | TooManyLoginFailuresException e) {
            if (getConfiguration().showLockedOutUserMessage()) {
              throw e;
            } else {
              // Do not give away information about the existence or status of a user
              throw new InvalidUsernamePasswordCombinationException(username, false, e);
            }
          }

          AmbariUserDetails userDetails = new AmbariUserDetailsImpl(users.getUser(userEntity), null, users.getUserAuthorities(userEntity));
          return new AmbariUserAuthentication(null, userDetails, true);
        }
      } catch (AuthenticationException e) {
        LOG.debug("Got exception during LDAP authentication attempt", e);
        // Try to help in troubleshooting
        Throwable cause = e.getCause();
        if ((cause != null) && (cause != e)) {
          // Below we check the cause of an AuthenticationException to see what the actual cause is
          // and then send an appropriate message to the caller.
          if (cause instanceof org.springframework.ldap.CommunicationException) {
            if (LOG.isDebugEnabled()) {
              LOG.warn("Failed to communicate with the LDAP server: " + cause.getMessage(), e);
            } else {
              LOG.warn("Failed to communicate with the LDAP server: " + cause.getMessage());
            }
          } else if (cause instanceof org.springframework.ldap.AuthenticationException) {
            LOG.warn("Looks like LDAP manager credentials (that are used for " +
                "connecting to LDAP server) are invalid.", e);
          }
        }
        throw new InvalidUsernamePasswordCombinationException(username, e);
      } catch (IncorrectResultSizeDataAccessException multipleUsersFound) {
        String message = ldapConfigurationProvider.get().isLdapAlternateUserSearchEnabled()
            ? String.format("Login Failed: Please append your domain to your username and try again.  Example: %s@domain", username)
            : "Login Failed: More than one user with that username found, please work with your Ambari Administrator to adjust your LDAP configuration";

        throw new DuplicateLdapUserFoundAuthenticationException(message);
      }
    } else {
      return null;
    }
  }

  @Inject public  AmbariLdapAuthenticationProvider(Users users, Configuration configuration, AmbariLdapConfigurationProvider ldapConfigurationProvider,
                                          AmbariLdapAuthoritiesPopulator authoritiesPopulator);

}