Repository: ambari Updated Branches: refs/heads/trunk a54d60918 -> 5beed88e1
AMBARI-18365. Add Ambari configuration options to support Kerberos token authentication (rlevas) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5beed88e Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5beed88e Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5beed88e Branch: refs/heads/trunk Commit: 5beed88e1a7ab422d619a445f8f8e892844d5fa4 Parents: a54d609 Author: Robert Levas <rle...@hortonworks.com> Authored: Wed Sep 14 09:21:14 2016 -0400 Committer: Robert Levas <rle...@hortonworks.com> Committed: Wed Sep 14 09:21:18 2016 -0400 ---------------------------------------------------------------------- .../server/configuration/Configuration.java | 181 +++++++++++++++++++ .../AmbariKerberosAuthenticationProperties.java | 161 +++++++++++++++++ .../server/configuration/ConfigurationTest.java | 136 +++++++++++++- ...ariKerberosAuthenticationPropertiesTest.java | 84 +++++++++ 4 files changed, 561 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/5beed88e/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 0690ca8..b2fa4c0 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 @@ -58,7 +58,9 @@ import org.apache.ambari.server.orm.PersistenceType; import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO; import org.apache.ambari.server.orm.entities.StageEntity; import org.apache.ambari.server.security.ClientSecurityType; +import org.apache.ambari.server.security.authentication.kerberos.AmbariKerberosAuthenticationProperties; import org.apache.ambari.server.security.authorization.LdapServerProperties; +import org.apache.ambari.server.security.authorization.UserType; import org.apache.ambari.server.security.authorization.jwt.JwtAuthenticationProperties; import org.apache.ambari.server.security.encryption.CertificateUtils; import org.apache.ambari.server.security.encryption.CredentialProvider; @@ -71,6 +73,7 @@ import org.apache.ambari.server.utils.DateUtils; import org.apache.ambari.server.utils.HostUtils; import org.apache.ambari.server.utils.Parallel; import org.apache.ambari.server.utils.ShellCommandUtil; +import org.apache.ambari.server.utils.StageUtils; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; @@ -1322,6 +1325,49 @@ public class Configuration { public static final ConfigurationProperty<String> JWT_ORIGINAL_URL_QUERY_PARAM = new ConfigurationProperty<>( "authentication.jwt.originalUrlParamName", "originalUrl"); + /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * Kerberos authentication-specific properties + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ + /** + * Determines whether to use Kerberos (SPNEGO) authentication when connecting Ambari. + */ + @Markdown(description = "Determines whether to use Kerberos (SPNEGO) authentication when connecting Ambari.") + public static final ConfigurationProperty<Boolean> KERBEROS_AUTH_ENABLED = new ConfigurationProperty<>( + "authentication.kerberos.enabled", Boolean.FALSE); + + /** + * The Kerberos principal name to use when verifying user-supplied Kerberos tokens for authentication via SPNEGO. + */ + @Markdown(description = "The Kerberos principal name to use when verifying user-supplied Kerberos tokens for authentication via SPNEGO") + public static final ConfigurationProperty<String> KERBEROS_AUTH_SPNEGO_PRINCIPAL = new ConfigurationProperty<>( + "authentication.kerberos.spnego.principal", "HTTP/_HOST"); + + /** + * The Kerberos identity to use when verifying user-supplied Kerberos tokens for authentication via SPNEGO. + */ + @Markdown(description = "The Kerberos keytab file to use when verifying user-supplied Kerberos tokens for authentication via SPNEGO") + public static final ConfigurationProperty<String> KERBEROS_AUTH_SPNEGO_KEYTAB_FILE = new ConfigurationProperty<>( + "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. + */ + @Markdown(description = "The auth-to-local rules set to use when translating a user's principal name to a local user name during authentication via SPNEGO.") + public static final ConfigurationProperty<String> KERBEROS_AUTH_AUTH_TO_LOCAL_RULES = new ConfigurationProperty<>( + "authentication.kerberos.auth_to_local.rules", "DEFAULT"); + /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * Kerberos authentication-specific properties (end) + * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ + /** * The type of connection pool to use with JDBC connections to the database. */ @@ -2318,6 +2364,11 @@ public class Configuration { private Map<String, String> databaseConnectorNames = new HashMap<>(); private Map<String, String> databasePreviousConnectorNames = new HashMap<>(); + /** + * The Kerberos authentication-specific properties container (for convenience) + */ + private final AmbariKerberosAuthenticationProperties kerberosAuthenticationProperties; + static { if (System.getProperty("os.name").contains("Windows")) { DEF_ARCHIVE_EXTENSION = ".zip"; @@ -2523,6 +2574,9 @@ public class Configuration { configsMap.put(CLIENT_API_SSL_CRT_PASS.getKey(), password); } + // Capture the Kerberos authentication-related properties + kerberosAuthenticationProperties = createKerberosAuthenticationProperties(); + loadSSLParams(); } @@ -4581,6 +4635,15 @@ public class Configuration { } /** + * Gets the Kerberos authentication-specific properties container + * + * @return an AmbariKerberosAuthenticationProperties + */ + public AmbariKerberosAuthenticationProperties getKerberosAuthenticationProperties() { + return kerberosAuthenticationProperties; + } + + /** * Ambari server temp dir * @return server temp dir */ @@ -5188,4 +5251,122 @@ public class Configuration { String value(); } + /** + * Creates an AmbariKerberosAuthenticationProperties instance containing the Kerberos authentication-specific + * properties. + * + * The relevant properties are processed to set any default values or translate the propery values + * into usable data for the Kerberos authentication logic. + * + * @return + */ + private AmbariKerberosAuthenticationProperties createKerberosAuthenticationProperties() { + AmbariKerberosAuthenticationProperties kerberosAuthProperties = new AmbariKerberosAuthenticationProperties(); + + kerberosAuthProperties.setKerberosAuthenticationEnabled(Boolean.valueOf(getProperty(KERBEROS_AUTH_ENABLED))); + + // if Kerberos authentication is enabled, continue; else ignore the rest of related properties since + // they will not be used. + if (!kerberosAuthProperties.isKerberosAuthenticationEnabled()) { + 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<UserType> orderedUserTypes = new ArrayList<UserType>(); + + String[] types = userTypes.split(","); + for (String type : types) { + type = type.trim(); + + if (!type.isEmpty()) { + try { + orderedUserTypes.add(UserType.valueOf(type.toUpperCase())); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(String.format("While processing ordered user types from %s, " + + "%s was found to be an invalid user type.", + KERBEROS_AUTH_USER_TYPES.getKey(), type), 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(UserType.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); + + if ((spnegoPrincipalName != null) && (spnegoPrincipalName.contains("_HOST"))) { + String hostName = StageUtils.getHostName(); + + if (StringUtils.isEmpty(hostName)) { + LOG.warn("Cannot replace _HOST in the configured SPNEGO principal name with the host name this host since it is not available"); + } else { + LOG.info("Replacing _HOST in the configured SPNEGO principal name with the host name this host: {}", hostName); + spnegoPrincipalName = spnegoPrincipalName.replaceAll("_HOST", hostName); + } + } + + kerberosAuthProperties.setSpnegoPrincipalName(spnegoPrincipalName); + + // Validate the SPNEGO principal name to ensure it was set. + // Log any found issues. + if (StringUtils.isEmpty(kerberosAuthProperties.getSpnegoPrincipalName())) { + throw new IllegalArgumentException(String.format("The SPNEGO principal name specified in %s is empty. " + + "This will cause issues authenticating users using Kerberos.", + KERBEROS_AUTH_SPNEGO_PRINCIPAL.getKey())); + } + + // Get the SPNEGO keytab file. There is nothing special to process for this value. + kerberosAuthProperties.setSpnegoKeytabFilePath(getProperty(KERBEROS_AUTH_SPNEGO_KEYTAB_FILE)); + + // Validate the SPNEGO keytab file to ensure it was set, it exists and it is readable by Ambari. + // Log any found issues. + if (StringUtils.isEmpty(kerberosAuthProperties.getSpnegoKeytabFilePath())) { + throw new IllegalArgumentException(String.format("The SPNEGO keytab file path specified in %s is empty. " + + "This will cause issues authenticating users using Kerberos.", + KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey())); + } else { + File keytabFile = new File(kerberosAuthProperties.getSpnegoKeytabFilePath()); + if (!keytabFile.exists()) { + throw new IllegalArgumentException(String.format("The SPNEGO keytab file path (%s) specified in %s does not exist. " + + "This will cause issues authenticating users using Kerberos.", + keytabFile.getAbsolutePath(), KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey())); + } else if (!keytabFile.canRead()) { + throw new IllegalArgumentException(String.format("The SPNEGO keytab file path (%s) specified in %s cannot be read. " + + "This will cause issues authenticating users using Kerberos.", + keytabFile.getAbsolutePath(), KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey())); + } + } + + // Get the auth-to-local rule set. There is nothing special to process for this value. + kerberosAuthProperties.setAuthToLocalRules(getProperty(KERBEROS_AUTH_AUTH_TO_LOCAL_RULES)); + + LOG.info("Kerberos authentication is enabled:\n " + + "\t{}: {}\n" + + "\t{}: {}\n" + + "\t{}: {}\n" + + "\t{}: {}\n" + + "\t{}: {}\n", + KERBEROS_AUTH_ENABLED.getKey(), + kerberosAuthProperties.isKerberosAuthenticationEnabled(), + KERBEROS_AUTH_SPNEGO_PRINCIPAL.getKey(), + 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()); + + return kerberosAuthProperties; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/5beed88e/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 new file mode 100644 index 0000000..bf8cabc --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authentication/kerberos/AmbariKerberosAuthenticationProperties.java @@ -0,0 +1,161 @@ +/* + * 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.kerberos; + +import org.apache.ambari.server.security.authorization.UserType; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * AmbariKerberosAuthenticationProperties is a container for Kerberos authentication-related + * configuration properties. This container holds interpreted configuration data to be used when + * authenticating users using Kerberos. + * <p> + * If Kerberos authentication is not enabled for Ambari <code>{@link #kerberosAuthenticationEnabled} == false</code>, + * then there is no guarantee that any other property in this container is valid. + */ +public class AmbariKerberosAuthenticationProperties { + + /** + * A boolean value indicating whether Kerberos authentication is enabled in Ambari (<code>true</code>) + * or not (<code>false</code>). + */ + private boolean kerberosAuthenticationEnabled = false; + + /** + * The SPNEGO principal name + */ + private String spnegoPrincipalName = null; + + /** + * The (absolute) path to the SPNEGO keytab file + */ + private String spnegoKeytabFilePath = null; + + /** + * A list of {@link UserType}s in order of preference for use when looking up user accounts in the + * Ambari database + */ + private List<UserType> orderedUserTypes = Collections.emptyList(); + + /** + * Auth-to-local rules to use to feed to an auth-to-local rules processor used to translate + * principal names to local user names. + */ + private String authToLocalRules; + + /** + * Get whether Kerberos authentication is enabled or not. + * + * @return <code>true</code> if Kerberos authentication is enabled; otherwise <code>false</code> + */ + public boolean isKerberosAuthenticationEnabled() { + return kerberosAuthenticationEnabled; + } + + /** + * Sets whether Kerberos authentication is enabled or not. + * + * @param kerberosAuthenticationEnabled <code>true</code> if Kerberos authentication is enabled; otherwise <code>false</code> + */ + public void setKerberosAuthenticationEnabled(boolean kerberosAuthenticationEnabled) { + this.kerberosAuthenticationEnabled = kerberosAuthenticationEnabled; + } + + /** + * Gets the configured SPNEGO principal name. This may be <code>null</code> if Kerberos + * authentication is not enabled. + * + * @return the SPNEGO principal name or <code>null</code> if Kerberos authentication is not enabled + */ + public String getSpnegoPrincipalName() { + return spnegoPrincipalName; + } + + /** + * Sets the configured SPNEGO principal name. + * + * @param spnegoPrincipalName a principal name + */ + public void setSpnegoPrincipalName(String spnegoPrincipalName) { + this.spnegoPrincipalName = spnegoPrincipalName; + } + + /** + * Gets the configured SPNEGO keytab file path. This may be <code>null</code> if Kerberos + * authentication is not enabled. + * + * @return the SPNEGO keytab file path or <code>null</code> if Kerberos authentication is not enabled + */ + public String getSpnegoKeytabFilePath() { + return spnegoKeytabFilePath; + } + + /** + * Sets the configured SPNEGO keytab file path. + * + * @param spnegoKeytabFilePath a keytab file path + */ + public void setSpnegoKeytabFilePath(String spnegoKeytabFilePath) { + this.spnegoKeytabFilePath = spnegoKeytabFilePath; + } + + /** + * Sets the list of {@link UserType}s (in preference order) to use to look up uer accounts in the Ambari database. + * + * @param orderedUserTypes a list of {@link UserType}s + */ + public void setOrderedUserTypes(List<UserType> orderedUserTypes) { + if (orderedUserTypes == null) { + this.orderedUserTypes = Collections.emptyList(); + } else { + this.orderedUserTypes = Collections.unmodifiableList(new ArrayList<UserType>(orderedUserTypes)); + } + } + + /** + * Gets the list of {@link UserType}s (in preference order) to use to look up uer accounts in the Ambari database. + * + * @return a list of {@link UserType}s + */ + public List<UserType> getOrderedUserTypes() { + return orderedUserTypes; + } + + /** + * Gets the configured auth-to-local rule set. This may be <code>null</code> if Kerberos + * authentication is not enabled. + * + * @return a string representing an auth-to-local rule set or <code>null</code> if Kerberos authentication is not enabled + */ + public String getAuthToLocalRules() { + return authToLocalRules; + } + + /** + * Sets the configured auth-to-local rule set. + * + * @param authToLocalRules a string representing an auth-to-local rule set + */ + public void setAuthToLocalRules(String authToLocalRules) { + this.authToLocalRules = authToLocalRules; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/5beed88e/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 f9b76f8..a56ace5 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 @@ -1,4 +1,4 @@ -/** +/* * 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 @@ -30,6 +30,8 @@ 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; @@ -40,8 +42,11 @@ import org.apache.ambari.server.configuration.Configuration.ConfigurationPropert import org.apache.ambari.server.configuration.Configuration.ConnectionPoolType; 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.UserType; import org.apache.ambari.server.state.services.MetricsRetrievalService; +import org.apache.ambari.server.utils.StageUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; @@ -855,6 +860,135 @@ public class ConfigurationTest { } /** + * Tests that the Kerberos-authentication properties are read and properly and set in an + * {@link AmbariKerberosAuthenticationProperties} instance when Kerberos authentication is enabled. + */ + @Test + public void testKerberosAuthenticationEnabled() throws IOException { + File keytabFile = temp.newFile("spnego.service.keytab"); + + Properties properties = new Properties(); + 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); + + AmbariKerberosAuthenticationProperties kerberosAuthenticationProperties = configuration.getKerberosAuthenticationProperties(); + + Assert.assertTrue(kerberosAuthenticationProperties.isKerberosAuthenticationEnabled()); + Assert.assertEquals(keytabFile.getAbsolutePath(), kerberosAuthenticationProperties.getSpnegoKeytabFilePath()); + Assert.assertEquals("spnego/principal@REALM", kerberosAuthenticationProperties.getSpnegoPrincipalName()); + Assert.assertEquals("DEFAULT", kerberosAuthenticationProperties.getAuthToLocalRules()); + Assert.assertEquals(Arrays.asList(UserType.LDAP, UserType.LOCAL), kerberosAuthenticationProperties.getOrderedUserTypes()); + } + + /** + * Tests that the Kerberos-authentication properties are read and properly and set in an + * {@link AmbariKerberosAuthenticationProperties} instance when Kerberos authentication is enabled + * and default values are expected to be used for unset properties. + */ + @Test + public void testKerberosAuthenticationEnabledUsingDefaults() throws IOException { + File keytabFile = temp.newFile("spnego.service.keytab"); + + Properties properties = new Properties(); + properties.put(Configuration.KERBEROS_AUTH_ENABLED.getKey(), "true"); + // Force a specific path to the SPNEGO keytab file since internal validation expects to exist + properties.put(Configuration.KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey(), keytabFile.getAbsolutePath()); + + Configuration configuration = new Configuration(properties); + + AmbariKerberosAuthenticationProperties kerberosAuthenticationProperties = configuration.getKerberosAuthenticationProperties(); + + Assert.assertTrue(kerberosAuthenticationProperties.isKerberosAuthenticationEnabled()); + Assert.assertEquals(keytabFile.getAbsolutePath(), kerberosAuthenticationProperties.getSpnegoKeytabFilePath()); + Assert.assertEquals("HTTP/" + StageUtils.getHostName(), kerberosAuthenticationProperties.getSpnegoPrincipalName()); + Assert.assertEquals("DEFAULT", kerberosAuthenticationProperties.getAuthToLocalRules()); + Assert.assertEquals(Collections.singletonList(UserType.LDAP), kerberosAuthenticationProperties.getOrderedUserTypes()); + } + + /** + * Tests that the Kerberos-authentication properties are read and properly set in an + * {@link AmbariKerberosAuthenticationProperties} instance when Kerberos authentication is disabled. + */ + @Test + public void testKerberosAuthenticationDisabled() { + Properties properties = new Properties(); + properties.put(Configuration.KERBEROS_AUTH_ENABLED.getKey(), "false"); + + Configuration configuration = new Configuration(properties); + + AmbariKerberosAuthenticationProperties kerberosAuthenticationProperties = configuration.getKerberosAuthenticationProperties(); + + Assert.assertFalse(kerberosAuthenticationProperties.isKerberosAuthenticationEnabled()); + Assert.assertNull(kerberosAuthenticationProperties.getSpnegoKeytabFilePath()); + Assert.assertNull(kerberosAuthenticationProperties.getSpnegoPrincipalName()); + Assert.assertNull(kerberosAuthenticationProperties.getAuthToLocalRules()); + Assert.assertEquals(Collections.emptyList(), kerberosAuthenticationProperties.getOrderedUserTypes()); + } + + @Test + public void testKerberosAuthenticationDisabledWithValuesSet() { + Properties properties = new Properties(); + 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); + + AmbariKerberosAuthenticationProperties kerberosAuthenticationProperties = configuration.getKerberosAuthenticationProperties(); + + Assert.assertFalse(kerberosAuthenticationProperties.isKerberosAuthenticationEnabled()); + Assert.assertNull(kerberosAuthenticationProperties.getSpnegoKeytabFilePath()); + Assert.assertNull(kerberosAuthenticationProperties.getSpnegoPrincipalName()); + Assert.assertNull(kerberosAuthenticationProperties.getAuthToLocalRules()); + Assert.assertEquals(Collections.emptyList(), kerberosAuthenticationProperties.getOrderedUserTypes()); + } + + @Test(expected = IllegalArgumentException.class) + public void testKerberosAuthenticationEmptySPNEGOPrincipalName() throws IOException { + File keytabFile = temp.newFile("spnego.service.keytab"); + + Properties properties = new Properties(); + 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); + } + + @Test(expected = IllegalArgumentException.class) + public void testKerberosAuthenticationEmptySPNEGOKeytabFile() { + Properties properties = new Properties(); + 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); + } + + @Test(expected = IllegalArgumentException.class) + public void testKerberosAuthenticationSPNEGOKeytabFileNotFound() { + Properties properties = new Properties(); + properties.put(Configuration.KERBEROS_AUTH_ENABLED.getKey(), "true"); + properties.put(Configuration.KERBEROS_AUTH_SPNEGO_KEYTAB_FILE.getKey(), "/path/to/missing/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"); + + new Configuration(properties); + } + + /** * Tests the default values for the {@link MetricsRetrievalService}. * * @throws Exception http://git-wip-us.apache.org/repos/asf/ambari/blob/5beed88e/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/kerberos/AmbariKerberosAuthenticationPropertiesTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/kerberos/AmbariKerberosAuthenticationPropertiesTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/kerberos/AmbariKerberosAuthenticationPropertiesTest.java new file mode 100644 index 0000000..d5ffc73 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authentication/kerberos/AmbariKerberosAuthenticationPropertiesTest.java @@ -0,0 +1,84 @@ +/* + * 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.kerberos; + +import org.apache.ambari.server.security.authorization.UserType; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +public class AmbariKerberosAuthenticationPropertiesTest { + @Test + public void testKerberosAuthenticationEnabled() throws Exception { + AmbariKerberosAuthenticationProperties properties = new AmbariKerberosAuthenticationProperties(); + + properties.setKerberosAuthenticationEnabled(true); + Assert.assertEquals(true, properties.isKerberosAuthenticationEnabled()); + + properties.setKerberosAuthenticationEnabled(false); + Assert.assertEquals(false, properties.isKerberosAuthenticationEnabled()); + } + + @Test + public void testSpnegoPrincipalName() throws Exception { + AmbariKerberosAuthenticationProperties properties = new AmbariKerberosAuthenticationProperties(); + + properties.setSpnegoPrincipalName("HTTP/_h...@example.com"); + Assert.assertEquals("HTTP/_h...@example.com", properties.getSpnegoPrincipalName()); + + properties.setSpnegoPrincipalName("something else"); + Assert.assertEquals("something else", properties.getSpnegoPrincipalName()); + } + + @Test + public void testSpnegoKeytabFilePath() throws Exception { + AmbariKerberosAuthenticationProperties properties = new AmbariKerberosAuthenticationProperties(); + + properties.setSpnegoKeytabFilePath("/etc/security/keytabs/spnego.service.keytab"); + Assert.assertEquals("/etc/security/keytabs/spnego.service.keytab", properties.getSpnegoKeytabFilePath()); + + properties.setSpnegoKeytabFilePath("something else"); + Assert.assertEquals("something else", properties.getSpnegoKeytabFilePath()); + } + + @Test + public void testOrderedUserTypes() throws Exception { + AmbariKerberosAuthenticationProperties properties = new AmbariKerberosAuthenticationProperties(); + + properties.setOrderedUserTypes(new ArrayList<UserType>(Arrays.asList(UserType.LDAP, UserType.LOCAL))); + Assert.assertEquals(new ArrayList<UserType>(Arrays.asList(UserType.LDAP, UserType.LOCAL)), properties.getOrderedUserTypes()); + + properties.setOrderedUserTypes(Collections.singletonList(UserType.JWT)); + Assert.assertEquals(new ArrayList<UserType>(Collections.singletonList(UserType.JWT)), properties.getOrderedUserTypes()); + } + + @Test + public void testAuthToLocalRules() throws Exception { + AmbariKerberosAuthenticationProperties properties = new AmbariKerberosAuthenticationProperties(); + + properties.setAuthToLocalRules("RULE:[1:$1@$0](us...@example.com)s/.*/user2/\\nDEFAULT"); + Assert.assertEquals("RULE:[1:$1@$0](us...@example.com)s/.*/user2/\\nDEFAULT", properties.getAuthToLocalRules()); + + properties.setAuthToLocalRules("something else"); + Assert.assertEquals("something else", properties.getAuthToLocalRules()); + } +} \ No newline at end of file