Repository: apex-core Updated Branches: refs/heads/master b102f59aa -> 3d0cefce5
APEXCORE-519 Added support for DIGEST authentication Project: http://git-wip-us.apache.org/repos/asf/apex-core/repo Commit: http://git-wip-us.apache.org/repos/asf/apex-core/commit/481e5298 Tree: http://git-wip-us.apache.org/repos/asf/apex-core/tree/481e5298 Diff: http://git-wip-us.apache.org/repos/asf/apex-core/diff/481e5298 Branch: refs/heads/master Commit: 481e5298307d6e2923bf89af30d177699ed6c147 Parents: bfc1eb8 Author: Pramod Immaneni <[email protected]> Authored: Wed Sep 14 17:09:11 2016 -0700 Committer: Pramod Immaneni <[email protected]> Committed: Mon Oct 3 15:21:42 2016 -0700 ---------------------------------------------------------------------- .../datatorrent/stram/security/AuthScheme.java | 2 +- .../datatorrent/stram/util/SecurityUtils.java | 30 +++++++----------- .../stram/util/WebServicesClient.java | 33 +++++++++++++------- .../stram/util/SecurityUtilsTest.java | 22 +++++++++---- .../stram/util/WebServicesClientTest.java | 12 +++++-- .../test/resources/security/dt-site-digest.xml | 33 ++++++++++++++++++++ 6 files changed, 93 insertions(+), 39 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/apex-core/blob/481e5298/engine/src/main/java/com/datatorrent/stram/security/AuthScheme.java ---------------------------------------------------------------------- diff --git a/engine/src/main/java/com/datatorrent/stram/security/AuthScheme.java b/engine/src/main/java/com/datatorrent/stram/security/AuthScheme.java index f39dddf..4545458 100644 --- a/engine/src/main/java/com/datatorrent/stram/security/AuthScheme.java +++ b/engine/src/main/java/com/datatorrent/stram/security/AuthScheme.java @@ -27,7 +27,7 @@ package com.datatorrent.stram.security; */ public enum AuthScheme { - BASIC("basic"), SPNEGO("kerberos"), KERBEROS("kerberos-standard"); + BASIC("basic"), DIGEST("digest"), SPNEGO("kerberos"), KERBEROS("kerberos-standard"); String name; http://git-wip-us.apache.org/repos/asf/apex-core/blob/481e5298/engine/src/main/java/com/datatorrent/stram/util/SecurityUtils.java ---------------------------------------------------------------------- diff --git a/engine/src/main/java/com/datatorrent/stram/util/SecurityUtils.java b/engine/src/main/java/com/datatorrent/stram/util/SecurityUtils.java index 349d09a..3985827 100644 --- a/engine/src/main/java/com/datatorrent/stram/util/SecurityUtils.java +++ b/engine/src/main/java/com/datatorrent/stram/util/SecurityUtils.java @@ -21,7 +21,6 @@ package com.datatorrent.stram.util; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.security.UserGroupInformation; -import com.datatorrent.api.Context; import com.datatorrent.api.Context.StramHTTPAuthentication; import com.datatorrent.stram.security.AuthScheme; import com.datatorrent.stram.security.StramUserLogin; @@ -37,13 +36,9 @@ public class SecurityUtils public static final String HADOOP_HTTP_AUTH_PROP = "hadoop.http.authentication.type"; private static final String HADOOP_HTTP_AUTH_VALUE_SIMPLE = "simple"; - private static boolean stramWebSecurityEnabled; - private static boolean hadoopWebSecurityEnabled; - - // If not initialized explicitly default to Hadoop auth - static { - hadoopWebSecurityEnabled = stramWebSecurityEnabled = UserGroupInformation.isSecurityEnabled(); - } + // If not initialized explicitly using init call, default to Hadoop auth for backwards compatibility + private static boolean stramWebSecurityEnabled = UserGroupInformation.isSecurityEnabled(); + private static boolean hadoopWebSecurityEnabled = stramWebSecurityEnabled; public static void init(Configuration configuration) { @@ -59,16 +54,15 @@ public class SecurityUtils initAuth(configuration); } // Stram http auth may not be specified and is null but still set a default - if (stramHTTPAuth != null) { - if (stramHTTPAuth == Context.StramHTTPAuthentication.FOLLOW_HADOOP_HTTP_AUTH) { - stramWebSecurityEnabled = hadoopWebSecurityEnabled; - } else if (stramHTTPAuth == StramHTTPAuthentication.FOLLOW_HADOOP_AUTH) { - stramWebSecurityEnabled = UserGroupInformation.isSecurityEnabled(); - } else if (stramHTTPAuth == StramHTTPAuthentication.ENABLE) { - stramWebSecurityEnabled = true; - } else if (stramHTTPAuth == StramHTTPAuthentication.DISABLE) { - stramWebSecurityEnabled = false; - } + if (stramHTTPAuth == StramHTTPAuthentication.FOLLOW_HADOOP_HTTP_AUTH) { + stramWebSecurityEnabled = hadoopWebSecurityEnabled; + } else if (stramHTTPAuth == StramHTTPAuthentication.ENABLE) { + stramWebSecurityEnabled = true; + } else if (stramHTTPAuth == StramHTTPAuthentication.DISABLE) { + stramWebSecurityEnabled = false; + } else { + // Default to StramHTTPAuthentication.FOLLOW_HADOOP_AUTH behavior + stramWebSecurityEnabled = UserGroupInformation.isSecurityEnabled(); } } http://git-wip-us.apache.org/repos/asf/apex-core/blob/481e5298/engine/src/main/java/com/datatorrent/stram/util/WebServicesClient.java ---------------------------------------------------------------------- diff --git a/engine/src/main/java/com/datatorrent/stram/util/WebServicesClient.java b/engine/src/main/java/com/datatorrent/stram/util/WebServicesClient.java index 73d5532..3b122b6 100644 --- a/engine/src/main/java/com/datatorrent/stram/util/WebServicesClient.java +++ b/engine/src/main/java/com/datatorrent/stram/util/WebServicesClient.java @@ -36,6 +36,7 @@ import org.apache.http.client.config.AuthSchemes; import org.apache.http.config.Lookup; import org.apache.http.config.RegistryBuilder; import org.apache.http.impl.auth.BasicSchemeFactory; +import org.apache.http.impl.auth.DigestSchemeFactory; import org.apache.http.impl.auth.KerberosSchemeFactory; import org.apache.http.impl.auth.SPNegoSchemeFactory; import org.apache.http.impl.client.BasicCookieStore; @@ -98,32 +99,40 @@ public class WebServicesClient credentialsProvider = new BasicCredentialsProvider(); // By default add SPNEGO so that it works even if auth is not explictly configured like before, in future // move it to auth setup below - registryBuilder.register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true)); - credentialsProvider.setCredentials(AuthScope.ANY, DEFAULT_TOKEN_CREDENTIALS); + setupHttpAuthScheme(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true), AuthScope.ANY, DEFAULT_TOKEN_CREDENTIALS); authRegistry = registryBuilder.build(); } public static void initAuth(ConfigProvider configuration) { - // Adding BASIC auth - AuthScheme scheme = AuthScheme.BASIC; + // Setting up BASIC and DIGEST auth + setupUserPassAuthScheme(AuthScheme.BASIC, AuthSchemes.BASIC, new BasicSchemeFactory(), configuration); + setupUserPassAuthScheme(AuthScheme.DIGEST, AuthSchemes.DIGEST, new DigestSchemeFactory(), configuration); + + // Adding kerberos standard auth + setupHttpAuthScheme(AuthSchemes.KERBEROS, new KerberosSchemeFactory(), AuthScope.ANY, DEFAULT_TOKEN_CREDENTIALS); + + authRegistry = registryBuilder.build(); + } + + private static void setupUserPassAuthScheme(AuthScheme scheme, String httpScheme, AuthSchemeProvider provider, ConfigProvider configuration) + { String username = configuration.getProperty(scheme, "username"); String password = configuration.getProperty(scheme, "password"); if ((username != null) && (password != null)) { LOG.info("Setting up scheme {}", scheme); - registryBuilder.register(AuthSchemes.BASIC, new BasicSchemeFactory()); - AuthScope authScope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.BASIC); + AuthScope authScope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, httpScheme); Credentials credentials = new UsernamePasswordCredentials(username, password); - credentialsProvider.setCredentials(authScope, credentials); + setupHttpAuthScheme(httpScheme, provider, authScope, credentials); } else if ((username != null) || (password != null)) { LOG.warn("Not setting up scheme {}, missing credentials {}", scheme, (username == null) ? "username" : "password"); } + } - // Adding kerberos standard auth - registryBuilder.register(AuthSchemes.KERBEROS, new KerberosSchemeFactory()); - credentialsProvider.setCredentials(AuthScope.ANY, DEFAULT_TOKEN_CREDENTIALS); - - authRegistry = registryBuilder.build(); + private static void setupHttpAuthScheme(String httpScheme, AuthSchemeProvider provider, AuthScope authScope, Credentials credentials) + { + registryBuilder.register(httpScheme, provider); + credentialsProvider.setCredentials(authScope, credentials); } public WebServicesClient() http://git-wip-us.apache.org/repos/asf/apex-core/blob/481e5298/engine/src/test/java/com/datatorrent/stram/util/SecurityUtilsTest.java ---------------------------------------------------------------------- diff --git a/engine/src/test/java/com/datatorrent/stram/util/SecurityUtilsTest.java b/engine/src/test/java/com/datatorrent/stram/util/SecurityUtilsTest.java index a2623fe..139b46a 100644 --- a/engine/src/test/java/com/datatorrent/stram/util/SecurityUtilsTest.java +++ b/engine/src/test/java/com/datatorrent/stram/util/SecurityUtilsTest.java @@ -34,7 +34,6 @@ public class SecurityUtilsTest @Test public void testStramWebSecurity() { - checkWebSecurity(false, false); Configuration conf = setupConfiguration(null); checkSecurityConfiguration(conf, new boolean[][]{{false, false}, {false, true}, {false, false}, {false, false}, {false, false}}); conf = setupConfiguration(AuthScheme.SPNEGO); @@ -42,11 +41,22 @@ public class SecurityUtilsTest } @Test - public void testInitAuth() throws NoSuchFieldException, IllegalAccessException + public void testBasicAuth() throws NoSuchFieldException, IllegalAccessException { - Configuration conf = setupConfiguration(AuthScheme.BASIC); + testAuthScheme(AuthScheme.BASIC); + } + + @Test + public void testDigestAuth() throws NoSuchFieldException, IllegalAccessException + { + testAuthScheme(AuthScheme.DIGEST); + } + + private void testAuthScheme(AuthScheme authScheme) throws NoSuchFieldException, IllegalAccessException + { + Configuration conf = setupConfiguration(authScheme); SecurityUtils.init(conf); - WebServicesClientTest.checkUserCredentials("testuser", "testpass"); + WebServicesClientTest.checkUserCredentials("testuser", "testpass", authScheme); } private Configuration setupConfiguration(AuthScheme authScheme) @@ -62,7 +72,7 @@ public class SecurityUtilsTest private void checkSecurityConfiguration(Configuration conf, boolean[][] securityConf) { Assert.assertEquals("Number variations", 5, securityConf.length); - SecurityUtils.init(conf, null); + SecurityUtils.init(conf); checkWebSecurity(securityConf[0][0], securityConf[0][1]); SecurityUtils.init(conf, Context.StramHTTPAuthentication.ENABLE); checkWebSecurity(securityConf[1][0], securityConf[1][1]); @@ -77,6 +87,6 @@ public class SecurityUtilsTest private void checkWebSecurity(boolean hadoopWebSecurity, boolean stramWebSecurity) { Assert.assertEquals("Hadoop web security", hadoopWebSecurity, SecurityUtils.isHadoopWebSecurityEnabled()); - Assert.assertEquals("Hadoop web security", stramWebSecurity, SecurityUtils.isStramWebSecurityEnabled()); + Assert.assertEquals("Stram web security", stramWebSecurity, SecurityUtils.isStramWebSecurityEnabled()); } } http://git-wip-us.apache.org/repos/asf/apex-core/blob/481e5298/engine/src/test/java/com/datatorrent/stram/util/WebServicesClientTest.java ---------------------------------------------------------------------- diff --git a/engine/src/test/java/com/datatorrent/stram/util/WebServicesClientTest.java b/engine/src/test/java/com/datatorrent/stram/util/WebServicesClientTest.java index fd422f0..8fb68e0 100644 --- a/engine/src/test/java/com/datatorrent/stram/util/WebServicesClientTest.java +++ b/engine/src/test/java/com/datatorrent/stram/util/WebServicesClientTest.java @@ -29,6 +29,8 @@ import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.AuthSchemes; +import com.datatorrent.stram.security.AuthScheme; + /** * */ @@ -45,11 +47,17 @@ public class WebServicesClientTest Assert.assertTrue("Filter present", webServicesClient.isFilterPresent(clientFilter)); } - public static void checkUserCredentials(String username, String password) throws NoSuchFieldException, + public static void checkUserCredentials(String username, String password, AuthScheme authScheme) throws NoSuchFieldException, IllegalAccessException { CredentialsProvider provider = getCredentialsProvider(); - AuthScope authScope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.BASIC); + String httpScheme = AuthScope.ANY_SCHEME; + if (authScheme == AuthScheme.BASIC) { + httpScheme = AuthSchemes.BASIC; + } else if (authScheme == AuthScheme.DIGEST) { + httpScheme = AuthSchemes.DIGEST; + } + AuthScope authScope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, httpScheme); Credentials credentials = provider.getCredentials(authScope); Assert.assertNotNull("Credentials", credentials); Assert.assertTrue("Credentials type is user", UsernamePasswordCredentials.class.isAssignableFrom(credentials.getClass())); http://git-wip-us.apache.org/repos/asf/apex-core/blob/481e5298/engine/src/test/resources/security/dt-site-digest.xml ---------------------------------------------------------------------- diff --git a/engine/src/test/resources/security/dt-site-digest.xml b/engine/src/test/resources/security/dt-site-digest.xml new file mode 100644 index 0000000..75ed76e --- /dev/null +++ b/engine/src/test/resources/security/dt-site-digest.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<!-- + + 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. + +--> + +<configuration> + <property> + <name>dt.authentication.digest.username</name> + <value>testuser</value> + </property> + <property> + <name>dt.authentication.digest.password</name> + <value>testpass</value> + </property> +</configuration>
