Repository: ambari Updated Branches: refs/heads/branch-feature-AMBARI-20859 160a6ec23 -> ceead2241
AMBARI-21223. Update Kerberos 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/ceead224 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ceead224 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ceead224 Branch: refs/heads/branch-feature-AMBARI-20859 Commit: ceead22412dc4385fe837884594e5aad57b884d7 Parents: 160a6ec Author: Robert Levas <[email protected]> Authored: Mon Oct 23 14:22:26 2017 -0400 Committer: Robert Levas <[email protected]> Committed: Mon Oct 23 14:22:26 2017 -0400 ---------------------------------------------------------------------- .../server/configuration/Configuration.java | 43 ------ .../server/orm/dao/UserAuthenticationDAO.java | 8 ++ .../orm/entities/UserAuthenticationEntity.java | 4 +- .../AmbariAuthenticationProvider.java | 25 ---- .../AmbariLocalAuthenticationProvider.java | 2 +- .../jwt/AmbariJwtAuthenticationProvider.java | 2 +- .../AmbariAuthToLocalUserDetailsService.java | 139 ++++++++++--------- .../AmbariKerberosAuthenticationProperties.java | 14 -- .../pam/AmbariPamAuthenticationProvider.java | 2 +- .../server/security/authorization/Users.java | 53 +++++-- ambari-server/src/main/python/ambari-server.py | 1 - .../main/python/ambari_server/kerberos_setup.py | 2 - .../server/configuration/ConfigurationTest.java | 11 -- ...uthenticationSourceResourceProviderTest.java | 2 +- .../AbstractAuthenticationProviderTest.java | 7 +- .../jwt/AmbariJwtAuthenticationFilterTest.java | 3 +- ...AmbariAuthToLocalUserDetailsServiceTest.java | 19 ++- .../AmbariPamAuthenticationProviderTest.java | 12 +- 18 files changed, 161 insertions(+), 188 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/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 205debc..a2326a0 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 @@ -66,7 +66,6 @@ import org.apache.ambari.server.security.ClientSecurityType; import org.apache.ambari.server.security.authentication.jwt.JwtAuthenticationProperties; import org.apache.ambari.server.security.authentication.kerberos.AmbariKerberosAuthenticationProperties; import org.apache.ambari.server.security.authorization.LdapServerProperties; -import org.apache.ambari.server.security.authorization.UserAuthenticationType; import org.apache.ambari.server.security.encryption.CertificateUtils; import org.apache.ambari.server.security.encryption.CredentialProvider; import org.apache.ambari.server.state.services.MetricsRetrievalService; @@ -1468,14 +1467,6 @@ public class Configuration { "authentication.kerberos.spnego.keytab.file", "/etc/security/keytabs/spnego.service.keytab"); /** - * A comma-delimited (ordered) list of preferred user types to use when finding the Ambari user - * account for the user-supplied Kerberos identity during authentication via SPNEGO. - */ - @Markdown(description = "A comma-delimited (ordered) list of preferred user types to use when finding the Ambari user account for the user-supplied Kerberos identity during authentication via SPNEGO") - public static final ConfigurationProperty<String> KERBEROS_AUTH_USER_TYPES = new ConfigurationProperty<>( - "authentication.kerberos.user.types", "LDAP"); - - /** * The auth-to-local rules set to use when translating a user's principal name to a local user name * during authentication via SPNEGO. */ @@ -6065,37 +6056,6 @@ public class Configuration { return kerberosAuthProperties; } - // Get and process the configured user type values to convert the comma-delimited string of - // user types into a ordered (as found in the comma-delimited value) list of UserType values. - String userTypes = getProperty(KERBEROS_AUTH_USER_TYPES); - List<UserAuthenticationType> orderedUserTypes = new ArrayList<>(); - - String[] types = userTypes.split(","); - for (String type : types) { - type = type.trim(); - - if (!type.isEmpty()) { - try { - orderedUserTypes.add(UserAuthenticationType.valueOf(type.toUpperCase())); - } catch (IllegalArgumentException e) { - String message = String.format("While processing ordered user types from %s, " + - "%s was found to be an invalid user type.", - KERBEROS_AUTH_USER_TYPES.getKey(), type); - LOG.error(message); - throw new IllegalArgumentException(message, e); - } - } - } - - // If no user types have been specified, assume only LDAP users... - if (orderedUserTypes.isEmpty()) { - LOG.info("No (valid) user types were specified in {}. Using the default value of LOCAL.", - KERBEROS_AUTH_USER_TYPES.getKey()); - orderedUserTypes.add(UserAuthenticationType.LDAP); - } - - kerberosAuthProperties.setOrderedUserTypes(orderedUserTypes); - // Get and process the SPNEGO principal name. If it exists and contains the host replacement // indicator (_HOST), replace it with the hostname of the current host. String spnegoPrincipalName = getProperty(KERBEROS_AUTH_SPNEGO_PRINCIPAL); @@ -6156,7 +6116,6 @@ public class Configuration { "\t{}: {}\n" + "\t{}: {}\n" + "\t{}: {}\n" + - "\t{}: {}\n" + "\t{}: {}\n", KERBEROS_AUTH_ENABLED.getKey(), kerberosAuthProperties.isKerberosAuthenticationEnabled(), @@ -6164,8 +6123,6 @@ public class Configuration { kerberosAuthProperties.getSpnegoPrincipalName(), KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey(), kerberosAuthProperties.getSpnegoKeytabFilePath(), - KERBEROS_AUTH_USER_TYPES.getKey(), - kerberosAuthProperties.getOrderedUserTypes(), KERBEROS_AUTH_AUTH_TO_LOCAL_RULES.getKey(), kerberosAuthProperties.getAuthToLocalRules()); http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserAuthenticationDAO.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserAuthenticationDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserAuthenticationDAO.java index c4e5cce..13c17f9 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserAuthenticationDAO.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserAuthenticationDAO.java @@ -58,6 +58,14 @@ public class UserAuthenticationDAO { return daoUtils.selectList(query); } + @RequiresSession + public List<UserAuthenticationEntity> findByTypeAndKey(UserAuthenticationType authenticationType, String key) { + TypedQuery<UserAuthenticationEntity> query = entityManagerProvider.get().createNamedQuery("UserAuthenticationEntity.findByTypeAndKey", UserAuthenticationEntity.class); + query.setParameter("authenticationType", authenticationType.name()); + query.setParameter("authenticationKey", (key == null) ? null : key.getBytes()); + return daoUtils.selectList(query); + } + @Transactional public void create(UserAuthenticationEntity entity) { entityManagerProvider.get().persist(entity); http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserAuthenticationEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserAuthenticationEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserAuthenticationEntity.java index fb78629..bba8cf2 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserAuthenticationEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserAuthenticationEntity.java @@ -50,7 +50,9 @@ import org.apache.commons.lang.builder.HashCodeBuilder; @NamedQuery(name = "UserAuthenticationEntity.findAll", query = "SELECT entity FROM UserAuthenticationEntity entity"), @NamedQuery(name = "UserAuthenticationEntity.findByType", - query = "SELECT entity FROM UserAuthenticationEntity entity where lower(entity.authenticationType)=lower(:authenticationType)") + query = "SELECT entity FROM UserAuthenticationEntity entity where lower(entity.authenticationType)=lower(:authenticationType)"), + @NamedQuery(name = "UserAuthenticationEntity.findByTypeAndKey", + query = "SELECT entity FROM UserAuthenticationEntity entity where lower(entity.authenticationType)=lower(:authenticationType) and entity.authenticationKey=:authenticationKey") }) @TableGenerator(name = "user_authentication_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value" http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/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 index 71fa175..0e5c913 100644 --- 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 @@ -50,31 +50,6 @@ public abstract class AmbariAuthenticationProvider implements AuthenticationProv } /** - * Validates the user account such that the user is allowed to log in. - * - * @param userEntity the user entity - * @param userName the Ambari username - */ - protected void validateLogin(UserEntity userEntity, String userName) { - if (userEntity == null) { - LOG.info("User not found"); - throw new UserNotFoundException(userName); - } else { - if (!userEntity.getActive()) { - LOG.info("User account is disabled: {}", userName); - throw new AccountDisabledException(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); - throw new TooManyLoginFailuresException(userName); - } - } - } - - /** * Finds the specific {@link UserAuthenticationEntity} from the collection of authentication methods * available to the specified {@link UserEntity}. * http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/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 index 3ffa3e8..9403da3 100644 --- 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 @@ -83,7 +83,7 @@ public class AmbariLocalAuthenticationProvider extends AmbariAuthenticationProvi LOG.debug("Authentication succeeded - a matching username and password were found: {}", userName); try { - validateLogin(userEntity, userName); + users.validateLogin(userEntity, userName); } catch (AccountDisabledException | TooManyLoginFailuresException e) { if (getConfiguration().showLockedOutUserMessage()) { http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/jwt/AmbariJwtAuthenticationProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/jwt/AmbariJwtAuthenticationProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/jwt/AmbariJwtAuthenticationProvider.java index 672444e..aec09fa 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/jwt/AmbariJwtAuthenticationProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/jwt/AmbariJwtAuthenticationProvider.java @@ -108,7 +108,7 @@ public class AmbariJwtAuthenticationProvider extends AmbariAuthenticationProvide // Ensure the user account is allowed to log in try { - validateLogin(userEntity, userName); + users.validateLogin(userEntity, userName); } catch (AccountDisabledException | TooManyLoginFailuresException e) { if (getConfiguration().showLockedOutUserMessage()) { throw e; http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariAuthToLocalUserDetailsService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariAuthToLocalUserDetailsService.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariAuthToLocalUserDetailsService.java index 261b94e..e04df5d 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariAuthToLocalUserDetailsService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariAuthToLocalUserDetailsService.java @@ -19,16 +19,20 @@ package org.apache.ambari.server.security.authentication.kerberos; import java.io.IOException; +import java.util.Collection; import java.util.List; import org.apache.ambari.server.AmbariException; 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.authentication.AuthenticationMethodNotAllowedException; +import org.apache.ambari.server.security.authentication.AccountDisabledException; +import org.apache.ambari.server.security.authentication.AmbariAuthenticationException; +import org.apache.ambari.server.security.authentication.TooManyLoginFailuresException; import org.apache.ambari.server.security.authentication.UserNotFoundException; import org.apache.ambari.server.security.authorization.UserAuthenticationType; import org.apache.ambari.server.security.authorization.Users; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.security.authentication.util.KerberosName; import org.slf4j.Logger; @@ -47,6 +51,8 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; public class AmbariAuthToLocalUserDetailsService implements UserDetailsService { private static final Logger LOG = LoggerFactory.getLogger(AmbariAuthToLocalUserDetailsService.class); + private final Configuration configuration; + private final Users users; private final String authToLocalRules; @@ -61,36 +67,44 @@ public class AmbariAuthToLocalUserDetailsService implements UserDetailsService { * @param users the Ambari users access object * @throws AmbariException if an error occurs parsing the user-provided auth-to-local rules */ - public AmbariAuthToLocalUserDetailsService(Configuration configuration, Users users) throws AmbariException { - String authToLocalRules = null; - - if (configuration != null) { - AmbariKerberosAuthenticationProperties properties = configuration.getKerberosAuthenticationProperties(); - - if (properties != null) { - authToLocalRules = properties.getAuthToLocalRules(); - } - } + AmbariAuthToLocalUserDetailsService(Configuration configuration, Users users) throws AmbariException { + AmbariKerberosAuthenticationProperties properties = configuration.getKerberosAuthenticationProperties(); + String authToLocalRules = properties.getAuthToLocalRules(); if (StringUtils.isEmpty(authToLocalRules)) { authToLocalRules = "DEFAULT"; } + this.configuration = configuration; this.users = users; this.authToLocalRules = authToLocalRules; } @Override public UserDetails loadUserByUsername(String principal) throws UsernameNotFoundException { - try { - String username; + String username; + + // First see if there is a Kerberos-related authentication record for some user. + Collection<UserAuthenticationEntity> entities = users.getUserAuthenticationEntities(UserAuthenticationType.KERBEROS, principal); + // Zero or one value is expected.. if not, that is an issue. + // If no entries are returned, we have not yet seen this principal. If no, perform an auth-to-local translation + // to determine what the local username is. + if (CollectionUtils.isEmpty(entities)) { // Since KerberosName relies on a static variable to hold on to the auth-to-local rules, attempt - // to protect access to the rule set by blocking other threads from chaning the rules out from + // to protect access to the rule set by blocking other threads from changing the rules out from // under us during this operation. Similar logic is used in org.apache.ambari.server.view.ViewContextImpl.getUsername(). - synchronized (KerberosName.class) { - KerberosName.setRules(authToLocalRules); - username = new KerberosName(principal).getShortName(); + try { + synchronized (KerberosName.class) { + KerberosName.setRules(authToLocalRules); + username = new KerberosName(principal).getShortName(); + } + } catch (UserNotFoundException e) { + throw new UsernameNotFoundException(e.getMessage(), e); + } catch (IOException e) { + String message = String.format("Failed to translate %s to a local username during Kerberos authentication: %s", principal, e.getLocalizedMessage()); + LOG.warn(message); + throw new UsernameNotFoundException(message, e); } if (username == null) { @@ -101,20 +115,17 @@ public class AmbariAuthToLocalUserDetailsService implements UserDetailsService { LOG.info("Translated {} to {} using auth-to-local rules during Kerberos authentication.", principal, username); return createUser(username, principal); - } catch (UserNotFoundException e) { - throw new UsernameNotFoundException(e.getMessage(), e); - } catch (IOException e) { - String message = String.format("Failed to translate %s to a local username during Kerberos authentication: %s", principal, e.getLocalizedMessage()); - LOG.warn(message); - throw new UsernameNotFoundException(message, e); + } else if (entities.size() == 1) { + UserEntity userEntity = entities.iterator().next().getUser(); + LOG.trace("Found KERBEROS authentication method for {} using principal {}", userEntity.getUserName(), principal); + return createUserDetails(userEntity); + } else { + throw new AmbariAuthenticationException("", "Unexpected error due to collisions on the principal name", false); } } /** * Given a username, finds an appropriate account in the Ambari database. - * <p> - * User accounts are searched in order of preferred user type as specified in the Ambari configuration - * ({@link Configuration#KERBEROS_AUTH_USER_TYPES}). * * @param username a username * @param principal the user's principal @@ -124,39 +135,35 @@ public class AmbariAuthToLocalUserDetailsService implements UserDetailsService { UserEntity userEntity = users.getUserEntity(username); if (userEntity == null) { + LOG.info("User not found: {} (from {})", username, principal); throw new UserNotFoundException(username, String.format("Cannot find user using Kerberos ticket (%s).", principal)); - } else if (!userEntity.getActive()) { - LOG.debug("User account is disabled"); - throw new UserNotFoundException(username, "User account is disabled"); } else { - // Check to see if the user is allowed to authenticate using KERBEROS or LDAP List<UserAuthenticationEntity> authenticationEntities = userEntity.getAuthenticationEntities(); boolean hasKerberos = false; - boolean hasLDAP = false; - boolean hasLocal = false; for (UserAuthenticationEntity entity : authenticationEntities) { UserAuthenticationType authenticationType = entity.getAuthenticationType(); switch (authenticationType) { case KERBEROS: - if (principal.equalsIgnoreCase(entity.getAuthenticationKey())) { + String key = entity.getAuthenticationKey(); + if (StringUtils.isEmpty(key) || key.equals(username)) { + LOG.trace("Found KERBEROS authentication method for {} where no principal was set. Fixing...", username); + // Fix this entry so that it contains the relevant principal.. + try { + users.addKerberosAuthentication(userEntity, principal); + users.removeAuthentication(userEntity, entity.getUserAuthenticationId()); + } catch (AmbariException e) { + // This should not lead to an error... if so, log it and ignore. + LOG.warn(String.format("Failed to create KERBEROS authentication method entry for %s with principal %s: %s", username, principal, e.getLocalizedMessage()), e); + } + hasKerberos = true; + } else if (principal.equalsIgnoreCase(entity.getAuthenticationKey())) { LOG.trace("Found KERBEROS authentication method for {} using principal {}", username, principal); hasKerberos = true; } break; - - case LDAP: - hasLDAP = true; - break; - - case LOCAL: - hasLocal = true; - break; - - default: - break; } if (hasKerberos) { @@ -164,32 +171,32 @@ public class AmbariAuthToLocalUserDetailsService implements UserDetailsService { } } + // TODO: Determine if KERBEROS users can be automatically added if (!hasKerberos) { - if (hasLDAP) { - // TODO: Determine if LDAP users can authenticate using Kerberos - try { - users.addKerberosAuthentication(userEntity, principal); - LOG.trace("Added KERBEROS authentication method for {} using principal {}", username, principal); - } catch (AmbariException e) { - LOG.error(String.format("Failed to add the KERBEROS authentication method for %s: %s", principal, e.getLocalizedMessage()), e); - } - hasKerberos = true; - } - - if (!hasKerberos && hasLocal) { - // TODO: Determine if LOCAL users can authenticate using Kerberos - try { - users.addKerberosAuthentication(userEntity, username); - LOG.trace("Added KERBEROS authentication method for {} using principal {}", username, principal); - } catch (AmbariException e) { - LOG.error(String.format("Failed to add the KERBEROS authentication method for %s: %s", username, e.getLocalizedMessage()), e); - } - hasKerberos = true; + try { + users.addKerberosAuthentication(userEntity, principal); + LOG.trace("Added KERBEROS authentication method for {} using principal {}", username, principal); + } catch (AmbariException e) { + LOG.error(String.format("Failed to add the KERBEROS authentication method for %s: %s", principal, e.getLocalizedMessage()), e); } } + } - if (!hasKerberos) { - throw new AuthenticationMethodNotAllowedException(username, UserAuthenticationType.KERBEROS); + return createUserDetails(userEntity); + } + + private UserDetails createUserDetails(UserEntity userEntity) { + String username = userEntity.getUserName(); + + // Ensure the user account is allowed to log in + try { + users.validateLogin(userEntity, username); + } catch (AccountDisabledException | TooManyLoginFailuresException e) { + if (configuration.showLockedOutUserMessage()) { + throw e; + } else { + // Do not give away information about the existence or status of a user + throw new AmbariAuthenticationException(username, "Unexpected error due to missing JWT token", false); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariKerberosAuthenticationProperties.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariKerberosAuthenticationProperties.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariKerberosAuthenticationProperties.java index 3e31e0d..a74cb82 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariKerberosAuthenticationProperties.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariKerberosAuthenticationProperties.java @@ -18,7 +18,6 @@ package org.apache.ambari.server.security.authentication.kerberos; -import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -119,19 +118,6 @@ public class AmbariKerberosAuthenticationProperties { } /** - * Sets the list of {@link UserAuthenticationType}s (in preference order) to use to look up uer accounts in the Ambari database. - * - * @param orderedUserTypes a list of {@link UserAuthenticationType}s - */ - public void setOrderedUserTypes(List<UserAuthenticationType> orderedUserTypes) { - if (orderedUserTypes == null) { - this.orderedUserTypes = Collections.emptyList(); - } else { - this.orderedUserTypes = Collections.unmodifiableList(new ArrayList<>(orderedUserTypes)); - } - } - - /** * Gets the list of {@link UserAuthenticationType}s (in preference order) to use to look up uer accounts in the Ambari database. * * @return a list of {@link UserAuthenticationType}s http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/pam/AmbariPamAuthenticationProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/pam/AmbariPamAuthenticationProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/pam/AmbariPamAuthenticationProvider.java index 824fbdf..ee6a39e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/pam/AmbariPamAuthenticationProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/pam/AmbariPamAuthenticationProvider.java @@ -136,7 +136,7 @@ public class AmbariPamAuthenticationProvider extends AmbariAuthenticationProvide } else { // Ensure the user is allowed to login.... try { - validateLogin(userEntity, ambariUsername); + users.validateLogin(userEntity, ambariUsername); } catch (AccountDisabledException | TooManyLoginFailuresException e) { if (getConfiguration().showLockedOutUserMessage()) { throw e; http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/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 a268467..ec05641 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 @@ -53,8 +53,12 @@ import org.apache.ambari.server.orm.entities.PrivilegeEntity; import org.apache.ambari.server.orm.entities.ResourceTypeEntity; import org.apache.ambari.server.orm.entities.UserAuthenticationEntity; import org.apache.ambari.server.orm.entities.UserEntity; +import org.apache.ambari.server.security.authentication.AccountDisabledException; +import org.apache.ambari.server.security.authentication.TooManyLoginFailuresException; +import org.apache.ambari.server.security.authentication.UserNotFoundException; import org.apache.ambari.server.security.ldap.LdapBatchDto; import org.apache.ambari.server.security.ldap.LdapUserGroupMemberDto; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -194,6 +198,31 @@ public class Users { } /** + * Validates the user account such that the user is allowed to log in. + * + * @param userEntity the user entity + * @param userName the Ambari username + */ + public void validateLogin(UserEntity userEntity, String userName) { + if (userEntity == null) { + LOG.info("User not found"); + throw new UserNotFoundException(userName); + } else { + if (!userEntity.getActive()) { + LOG.info("User account is disabled: {}", userName); + throw new AccountDisabledException(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); + throw new TooManyLoginFailuresException(userName); + } + } + } + + /** * Converts group to LDAP group. * * @param groupName group name @@ -1137,6 +1166,16 @@ public class Users { } /** + * + * @param authenticationType + * @param key + * @return + */ + public Collection<UserAuthenticationEntity> getUserAuthenticationEntities(UserAuthenticationType authenticationType, String key) { + return userAuthenticationDAO.findByTypeAndKey(authenticationType, key); + } + + /** * Modifies authentication key of an authentication source for a user * * @throws AmbariException @@ -1242,7 +1281,6 @@ public class Users { /** - * TODO: This is to be revisited for AMBARI-21217 (Update JWT Authentication process to work with improved user management facility) * Adds the ability for a user to authenticate using a JWT token. * <p> * The key for this authentication mechanism is the username expected to be in the JWT token. @@ -1268,7 +1306,6 @@ public class Users { } /** - * TODO: This is to be revisited for AMBARI-21223 (Update Kerberos Authentication process to work with improved user management facility) * Adds the ability for a user to authenticate using a Kerberos token. * * @param userEntity the user @@ -1278,14 +1315,9 @@ public class Users { public void addKerberosAuthentication(UserEntity userEntity, String principalName) throws AmbariException { addAuthentication(userEntity, UserAuthenticationType.KERBEROS, principalName, new Validator() { public void validate(UserEntity userEntity, String key) throws AmbariException { - List<UserAuthenticationEntity> authenticationEntities = userEntity.getAuthenticationEntities(); - - // Ensure only one UserAuthenticationEntity exists for LOCAL for the user... - for (UserAuthenticationEntity entity : authenticationEntities) { - if ((entity.getAuthenticationType() == UserAuthenticationType.KERBEROS) && - ((key == null) ? (entity.getAuthenticationKey() == null) : key.equals(entity.getAuthenticationKey()))) { - throw new AmbariException("The authentication type already exists for this user"); - } + // Ensure no other authentication entries exist for the same principal... + if (!CollectionUtils.isEmpty(userAuthenticationDAO.findByTypeAndKey(UserAuthenticationType.KERBEROS, key))) { + throw new AmbariException("The authentication type already exists for this principal"); } } }); @@ -1323,7 +1355,6 @@ public class Users { } /** - * TODO: This is to be revisited for AMBARI-21221 (Update Pam Authentication process to work with improved user management facility) * Adds the ability for a user to authenticate using Pam * * @param userEntity the user http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/main/python/ambari-server.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/ambari-server.py b/ambari-server/src/main/python/ambari-server.py index 8fcde77..5090de2 100755 --- a/ambari-server/src/main/python/ambari-server.py +++ b/ambari-server/src/main/python/ambari-server.py @@ -623,7 +623,6 @@ def init_kerberos_setup_parser_options(parser): parser.add_option('--kerberos-enabled', default=False, help="Kerberos enabled", dest="kerberos_enabled") parser.add_option('--kerberos-spnego-principal', default="HTTP/_HOST", help="Kerberos SPNEGO principal", dest="kerberos_spnego_principal") parser.add_option('--kerberos-spnego-keytab-file', default="/etc/security/keytabs/spnego.service.keytab", help="Kerberos SPNEGO keytab file", dest="kerberos_spnego_keytab_file") - parser.add_option('--kerberos-spnego-user-types', default="LDAP", help="User type search order (comma-delimited)", dest="kerberos_user_types") parser.add_option('--kerberos-auth-to-local-rules', default="DEFAULT", help="Auth-to-local rules", dest="kerberos_auth_to_local_rules") http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/main/python/ambari_server/kerberos_setup.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/ambari_server/kerberos_setup.py b/ambari-server/src/main/python/ambari_server/kerberos_setup.py index 74b2d3e..84820ef 100644 --- a/ambari-server/src/main/python/ambari_server/kerberos_setup.py +++ b/ambari-server/src/main/python/ambari_server/kerberos_setup.py @@ -50,8 +50,6 @@ def init_kerberos_properties_list(properties, options): REGEX_ANYTHING, False, "HTTP/_HOST"), KerberosPropertyTemplate(properties, options.kerberos_spnego_keytab_file, "authentication.kerberos.spnego.keytab.file", "SPNEGO keytab file {0}: ", REGEX_ANYTHING, False, "/etc/security/keytabs/spnego.service.keytab"), - KerberosPropertyTemplate(properties, options.kerberos_user_types, "authentication.kerberos.user.types", "User type search order [LDAP|LOCAL|JTW] {0}: ", - REGEX_ANYTHING, False, "LDAP"), KerberosPropertyTemplate(properties, options.kerberos_auth_to_local_rules, "authentication.kerberos.auth_to_local.rules", "Auth-to-local rules {0}: ", REGEX_ANYTHING, False, "DEFAULT") ] http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java b/ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java index 2b78f79..fdc4a2f 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java @@ -30,8 +30,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Collections; import java.util.Map; import java.util.Properties; @@ -44,7 +42,6 @@ import org.apache.ambari.server.configuration.Configuration.DatabaseType; import org.apache.ambari.server.controller.metrics.ThreadPoolEnabledPropertyProvider; import org.apache.ambari.server.security.authentication.kerberos.AmbariKerberosAuthenticationProperties; import org.apache.ambari.server.security.authorization.LdapServerProperties; -import org.apache.ambari.server.security.authorization.UserAuthenticationType; import org.apache.ambari.server.state.services.MetricsRetrievalService; import org.apache.ambari.server.utils.StageUtils; import org.apache.commons.io.FileUtils; @@ -894,7 +891,6 @@ public class ConfigurationTest { properties.put(Configuration.KERBEROS_AUTH_ENABLED.getKey(), "true"); properties.put(Configuration.KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey(), keytabFile.getAbsolutePath()); properties.put(Configuration.KERBEROS_AUTH_SPNEGO_PRINCIPAL.getKey(), "spnego/principal@REALM"); - properties.put(Configuration.KERBEROS_AUTH_USER_TYPES.getKey(), "LDAP, LOCAL"); properties.put(Configuration.KERBEROS_AUTH_AUTH_TO_LOCAL_RULES.getKey(), "DEFAULT"); Configuration configuration = new Configuration(properties); @@ -905,7 +901,6 @@ public class ConfigurationTest { Assert.assertEquals(keytabFile.getAbsolutePath(), kerberosAuthenticationProperties.getSpnegoKeytabFilePath()); Assert.assertEquals("spnego/principal@REALM", kerberosAuthenticationProperties.getSpnegoPrincipalName()); Assert.assertEquals("DEFAULT", kerberosAuthenticationProperties.getAuthToLocalRules()); - Assert.assertEquals(Arrays.asList(UserAuthenticationType.LDAP, UserAuthenticationType.LOCAL), kerberosAuthenticationProperties.getOrderedUserTypes()); } /** @@ -930,7 +925,6 @@ public class ConfigurationTest { Assert.assertEquals(keytabFile.getAbsolutePath(), kerberosAuthenticationProperties.getSpnegoKeytabFilePath()); Assert.assertEquals("HTTP/" + StageUtils.getHostName(), kerberosAuthenticationProperties.getSpnegoPrincipalName()); Assert.assertEquals("DEFAULT", kerberosAuthenticationProperties.getAuthToLocalRules()); - Assert.assertEquals(Collections.singletonList(UserAuthenticationType.LDAP), kerberosAuthenticationProperties.getOrderedUserTypes()); } /** @@ -950,7 +944,6 @@ public class ConfigurationTest { Assert.assertNull(kerberosAuthenticationProperties.getSpnegoKeytabFilePath()); Assert.assertNull(kerberosAuthenticationProperties.getSpnegoPrincipalName()); Assert.assertNull(kerberosAuthenticationProperties.getAuthToLocalRules()); - Assert.assertEquals(Collections.emptyList(), kerberosAuthenticationProperties.getOrderedUserTypes()); } @Test @@ -959,7 +952,6 @@ public class ConfigurationTest { properties.put(Configuration.KERBEROS_AUTH_ENABLED.getKey(), "false"); properties.put(Configuration.KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey(), "/path/to/spnego/keytab/file"); properties.put(Configuration.KERBEROS_AUTH_SPNEGO_PRINCIPAL.getKey(), "spnego/principal@REALM"); - properties.put(Configuration.KERBEROS_AUTH_USER_TYPES.getKey(), "LDAP, LOCAL"); properties.put(Configuration.KERBEROS_AUTH_AUTH_TO_LOCAL_RULES.getKey(), "DEFAULT"); Configuration configuration = new Configuration(properties); @@ -970,7 +962,6 @@ public class ConfigurationTest { Assert.assertNull(kerberosAuthenticationProperties.getSpnegoKeytabFilePath()); Assert.assertNull(kerberosAuthenticationProperties.getSpnegoPrincipalName()); Assert.assertNull(kerberosAuthenticationProperties.getAuthToLocalRules()); - Assert.assertEquals(Collections.emptyList(), kerberosAuthenticationProperties.getOrderedUserTypes()); } @Test(expected = IllegalArgumentException.class) @@ -981,7 +972,6 @@ public class ConfigurationTest { properties.put(Configuration.KERBEROS_AUTH_ENABLED.getKey(), "true"); properties.put(Configuration.KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey(), keytabFile.getAbsolutePath()); properties.put(Configuration.KERBEROS_AUTH_SPNEGO_PRINCIPAL.getKey(), ""); - properties.put(Configuration.KERBEROS_AUTH_USER_TYPES.getKey(), "LDAP, LOCAL"); properties.put(Configuration.KERBEROS_AUTH_AUTH_TO_LOCAL_RULES.getKey(), "DEFAULT"); new Configuration(properties); @@ -993,7 +983,6 @@ public class ConfigurationTest { properties.put(Configuration.KERBEROS_AUTH_ENABLED.getKey(), "true"); properties.put(Configuration.KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey(), ""); properties.put(Configuration.KERBEROS_AUTH_SPNEGO_PRINCIPAL.getKey(), "spnego/principal@REALM"); - properties.put(Configuration.KERBEROS_AUTH_USER_TYPES.getKey(), "LDAP, LOCAL"); properties.put(Configuration.KERBEROS_AUTH_AUTH_TO_LOCAL_RULES.getKey(), "DEFAULT"); new Configuration(properties); http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProviderTest.java index f109c68..a899d0d 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProviderTest.java @@ -260,7 +260,7 @@ public class UserAuthenticationSourceResourceProviderTest extends EasyMockSuppor entities.put("User100", createMockUserAuthenticationEntity("User100")); entities.put("admin", createMockUserAuthenticationEntity("admin")); - expect(users.getUserAuthenticationEntities(null, null)).andReturn(entities.values()).once(); + expect(users.getUserAuthenticationEntities((String)null, null)).andReturn(entities.values()).once(); } else { expect(users.getUserAuthenticationEntities("User1", null)).andReturn(entities.values()).once(); } http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/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 index 49e8a8f..b24935d 100644 --- 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 @@ -179,6 +179,11 @@ abstract class AbstractAuthenticationProviderTest extends EasyMockSupport { } protected Injector getInjector() { + final Users users = createMockBuilder(Users.class) + .addMockedMethod("getUserEntity", String.class) + .addMockedMethod("getUserAuthorities", UserEntity.class) + .createMock(); + return Guice.createInjector(new AbstractModule() { @Override protected void configure() { @@ -192,7 +197,7 @@ abstract class AbstractAuthenticationProviderTest extends EasyMockSupport { bind(HookService.class).toInstance(createMock(HookService.class)); bind(HookContextFactory.class).toInstance(createMock(HookContextFactory.class)); - bind(Users.class).toInstance(createMock(Users.class)); + bind(Users.class).toInstance(users); bind(Configuration.class).toInstance(configuration); } }, getAdditionalModule()); http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/jwt/AmbariJwtAuthenticationFilterTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/jwt/AmbariJwtAuthenticationFilterTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/jwt/AmbariJwtAuthenticationFilterTest.java index debfaf6..b600ae5 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/jwt/AmbariJwtAuthenticationFilterTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/jwt/AmbariJwtAuthenticationFilterTest.java @@ -404,7 +404,6 @@ public class AmbariJwtAuthenticationFilterTest extends EasyMockSupport { UserEntity userEntity = createMock(UserEntity.class); expect(userEntity.getAuthenticationEntities()).andReturn(Collections.singletonList(userAuthenticationEntity)).once(); expect(userEntity.getActive()).andReturn(true).atLeastOnce(); - expect(userEntity.getConsecutiveFailures()).andReturn(1).atLeastOnce(); expect(userEntity.getUserId()).andReturn(1).atLeastOnce(); expect(userEntity.getUserName()).andReturn("username").atLeastOnce(); expect(userEntity.getCreateTime()).andReturn(new Date()).atLeastOnce(); @@ -415,6 +414,8 @@ public class AmbariJwtAuthenticationFilterTest extends EasyMockSupport { Users users = createMock(Users.class); expect(users.getUserEntity("test-user")).andReturn(userEntity).once(); expect(users.getUserAuthorities(userEntity)).andReturn(Collections.emptyList()).once(); + users.validateLogin(userEntity, "test-user"); + expectLastCall().once(); AmbariAuthenticationEventHandler eventHandler = createNiceMock(AmbariAuthenticationEventHandler.class); eventHandler.beforeAttemptAuthentication(capture(captureFilter), eq(request), eq(response)); http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/kerberos/AmbariAuthToLocalUserDetailsServiceTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/kerberos/AmbariAuthToLocalUserDetailsServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/kerberos/AmbariAuthToLocalUserDetailsServiceTest.java index c6ee706..509909f 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/kerberos/AmbariAuthToLocalUserDetailsServiceTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/kerberos/AmbariAuthToLocalUserDetailsServiceTest.java @@ -19,6 +19,7 @@ package org.apache.ambari.server.security.authentication.kerberos; import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; import java.util.Collection; import java.util.Collections; @@ -26,6 +27,7 @@ import java.util.Collections; 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.authentication.UserNotFoundException; import org.apache.ambari.server.security.authorization.AmbariGrantedAuthority; import org.apache.ambari.server.security.authorization.UserAuthenticationType; import org.apache.ambari.server.security.authorization.Users; @@ -34,7 +36,6 @@ import org.junit.Before; import org.junit.Test; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; import junit.framework.Assert; @@ -54,19 +55,23 @@ public class AmbariAuthToLocalUserDetailsServiceTest extends EasyMockSupport { Configuration configuration = createMock(Configuration.class); expect(configuration.getKerberosAuthenticationProperties()).andReturn(properties).once(); + UserEntity userEntity = createMock(UserEntity.class); + UserAuthenticationEntity kerberosAuthenticationEntity = createMock(UserAuthenticationEntity.class); expect(kerberosAuthenticationEntity.getAuthenticationType()).andReturn(UserAuthenticationType.KERBEROS).anyTimes(); expect(kerberosAuthenticationEntity.getAuthenticationKey()).andReturn("[email protected]").anyTimes(); + expect(kerberosAuthenticationEntity.getUser()).andReturn(userEntity).anyTimes(); - UserEntity userEntity = createMock(UserEntity.class); - expect(userEntity.getActive()).andReturn(true).once(); - expect(userEntity.getAuthenticationEntities()).andReturn(Collections.singletonList(kerberosAuthenticationEntity)).once(); + expect(userEntity.getUserName()).andReturn("user1").atLeastOnce(); Collection<AmbariGrantedAuthority> userAuthorities = Collections.singletonList(createNiceMock(AmbariGrantedAuthority.class)); Users users = createMock(Users.class); - expect(users.getUserEntity("user1")).andReturn(userEntity).atLeastOnce(); expect(users.getUserAuthorities(userEntity)).andReturn(userAuthorities).atLeastOnce(); + expect(users.getUserAuthenticationEntities(UserAuthenticationType.KERBEROS, "[email protected]")) + .andReturn(Collections.singleton(kerberosAuthenticationEntity)).atLeastOnce(); + users.validateLogin(userEntity, "user1"); + expectLastCall().once(); replayAll(); @@ -82,7 +87,7 @@ public class AmbariAuthToLocalUserDetailsServiceTest extends EasyMockSupport { Assert.assertEquals("", userDetails.getPassword()); } - @Test(expected = UsernameNotFoundException.class) + @Test(expected = UserNotFoundException.class) public void loadUserByUsernameUserNotFound() throws Exception { AmbariKerberosAuthenticationProperties properties = new AmbariKerberosAuthenticationProperties(); @@ -91,6 +96,8 @@ public class AmbariAuthToLocalUserDetailsServiceTest extends EasyMockSupport { Users users = createMock(Users.class); expect(users.getUserEntity("user1")).andReturn(null).times(2); + expect(users.getUserAuthenticationEntities(UserAuthenticationType.KERBEROS, "[email protected]")) + .andReturn(null).atLeastOnce(); replayAll(); http://git-wip-us.apache.org/repos/asf/ambari/blob/ceead224/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/pam/AmbariPamAuthenticationProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/pam/AmbariPamAuthenticationProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/pam/AmbariPamAuthenticationProviderTest.java index 6908c55..3d4c088 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/pam/AmbariPamAuthenticationProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/pam/AmbariPamAuthenticationProviderTest.java @@ -69,6 +69,14 @@ public class AmbariPamAuthenticationProviderTest extends EasyMockSupport { @Before public void setup() { + final Users users = createMockBuilder(Users.class) + .addMockedMethod("getUserEntity", String.class) + .addMockedMethod("getUserAuthorities", UserEntity.class) + .addMockedMethod("createUser", String.class, String.class, String.class, Boolean.class) + .addMockedMethod("addPamAuthentication", UserEntity.class, String.class) + .addMockedMethod("getUser", UserEntity.class) + .createMock(); + injector = Guice.createInjector(new AbstractModule() { @Override @@ -80,7 +88,7 @@ public class AmbariPamAuthenticationProviderTest extends EasyMockSupport { bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class)); bind(PamAuthenticationFactory.class).toInstance(createMock(PamAuthenticationFactory.class)); bind(PasswordEncoder.class).toInstance(new StandardPasswordEncoder()); - bind(Users.class).toInstance(createMock(Users.class)); + bind(Users.class).toInstance(users); } }); @@ -264,7 +272,7 @@ public class AmbariPamAuthenticationProviderTest extends EasyMockSupport { userEntity.setActive(active); userEntity.setConsecutiveFailures(consecutiveFailures); - if(addAuthentication) { + if (addAuthentication) { UserAuthenticationEntity userAuthenticationEntity = new UserAuthenticationEntity(); userAuthenticationEntity.setAuthenticationType(UserAuthenticationType.PAM); userAuthenticationEntity.setAuthenticationKey(TEST_USER_NAME);
