This is an automated email from the ASF dual-hosted git repository.
prasanthj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new 24313ab HIVE-21783: Avoid authentication for connection from the same
domain (Ashutosh Bapat reviewed by Olli Draese, Prasanth Jayachandran)
24313ab is described below
commit 24313ab962b2881317bdcb50e67e90d3da3a5cc2
Author: Prasanth Jayachandran <[email protected]>
AuthorDate: Thu Jun 13 01:36:39 2019 -0700
HIVE-21783: Avoid authentication for connection from the same domain
(Ashutosh Bapat reviewed by Olli Draese, Prasanth Jayachandran)
---
.../java/org/apache/hadoop/hive/conf/HiveConf.java | 8 +
.../java/org/apache/hive/minikdc/MiniHiveKdc.java | 23 ++-
...estImproperTrustDomainAuthenticationBinary.java | 28 +++
.../TestImproperTrustDomainAuthenticationHttp.java | 28 +++
.../auth/TestTrustDomainAuthenticationBinary.java | 28 +++
.../auth/TestTrustDomainAuthenticationHttp.java | 28 +++
.../auth/TrustDomainAuthenticationTest.java | 192 +++++++++++++++++++++
.../apache/hive/service/auth/HiveAuthFactory.java | 5 +
.../apache/hive/service/auth/PlainSaslHelper.java | 54 ++++++
.../hive/service/cli/thrift/ThriftHttpServlet.java | 53 ++++--
10 files changed, 422 insertions(+), 25 deletions(-)
diff --git a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
index 2cea174..03a8019 100644
--- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
+++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
@@ -3478,6 +3478,14 @@ public class HiveConf extends Configuration {
" (Use with property
hive.server2.custom.authentication.class)\n" +
" PAM: Pluggable authentication module\n" +
" NOSASL: Raw transport"),
+ HIVE_SERVER2_TRUSTED_DOMAIN("hive.server2.trusted.domain", "",
+ "Specifies the host or a domain to trust connections from.
Authentication is skipped " +
+ "for any connection coming from a host whose hostname ends with the
value of this" +
+ " property. If authentication is expected to be skipped for
connections from " +
+ "only a given host, fully qualified hostname of that host should be
specified. By default" +
+ " it is empty, which means that all the connections to HiveServer2 are
authenticated. " +
+ "When it is non-empty, the client has to provide a Hive user name. Any
password, if " +
+ "provided, will not be used when authentication is skipped."),
HIVE_SERVER2_ALLOW_USER_SUBSTITUTION("hive.server2.allow.user.substitution",
true,
"Allow alternate user to be specified as part of HiveServer2 open
connection request."),
HIVE_SERVER2_KERBEROS_KEYTAB("hive.server2.authentication.kerberos.keytab", "",
diff --git
a/itests/hive-minikdc/src/test/java/org/apache/hive/minikdc/MiniHiveKdc.java
b/itests/hive-minikdc/src/test/java/org/apache/hive/minikdc/MiniHiveKdc.java
index 7d1192a..e604f90 100644
--- a/itests/hive-minikdc/src/test/java/org/apache/hive/minikdc/MiniHiveKdc.java
+++ b/itests/hive-minikdc/src/test/java/org/apache/hive/minikdc/MiniHiveKdc.java
@@ -36,6 +36,7 @@ import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hive.jdbc.miniHS2.MiniHS2;
import com.google.common.io.Files;
+import org.apache.hive.service.server.HiveServer2;
/**
* Wrapper around Hadoop's MiniKdc for use in hive tests.
@@ -178,15 +179,21 @@ public class MiniHiveKdc {
* @return new MiniHS2 instance
* @throws Exception
*/
- public static MiniHS2 getMiniHS2WithKerb(MiniHiveKdc miniHiveKdc, HiveConf
hiveConf,
+ public static MiniHS2 getMiniHS2WithKerb(MiniHiveKdc miniHiveKdc, HiveConf
hiveConf,
String authType) throws Exception {
- String hivePrincipal =
-
miniHiveKdc.getFullyQualifiedServicePrincipal(MiniHiveKdc.HIVE_SERVICE_PRINCIPAL);
- String hiveKeytab = miniHiveKdc.getKeyTabFile(
-
miniHiveKdc.getServicePrincipalForUser(MiniHiveKdc.HIVE_SERVICE_PRINCIPAL));
-
- return new MiniHS2.Builder().withConf(hiveConf).withMiniKdc(hivePrincipal,
hiveKeytab).
- withAuthenticationType(authType).build();
+ String hivePrincipal =
+
miniHiveKdc.getFullyQualifiedServicePrincipal(MiniHiveKdc.HIVE_SERVICE_PRINCIPAL);
+ String hiveKeytab = miniHiveKdc.getKeyTabFile(
+
miniHiveKdc.getServicePrincipalForUser(MiniHiveKdc.HIVE_SERVICE_PRINCIPAL));
+
+ MiniHS2.Builder miniHS2Builder = new MiniHS2.Builder()
+ .withConf(hiveConf)
+ .withMiniKdc(hivePrincipal,
hiveKeytab)
+
.withAuthenticationType(authType);
+ if (HiveServer2.isHTTPTransportMode(hiveConf)) {
+ miniHS2Builder.withHTTPTransport();
+ }
+ return miniHS2Builder.build();
}
/**
diff --git
a/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestImproperTrustDomainAuthenticationBinary.java
b/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestImproperTrustDomainAuthenticationBinary.java
new file mode 100644
index 0000000..b7a8bec
--- /dev/null
+++
b/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestImproperTrustDomainAuthenticationBinary.java
@@ -0,0 +1,28 @@
+/*
+ * 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.hive.service.auth;
+
+import org.junit.BeforeClass;
+
+public class TestImproperTrustDomainAuthenticationBinary extends
TrustDomainAuthenticationTest {
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ initialize(HS2_TRANSPORT_MODE_BINARY, false);
+ }
+}
diff --git
a/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestImproperTrustDomainAuthenticationHttp.java
b/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestImproperTrustDomainAuthenticationHttp.java
new file mode 100644
index 0000000..57bcf4f
--- /dev/null
+++
b/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestImproperTrustDomainAuthenticationHttp.java
@@ -0,0 +1,28 @@
+/*
+ * 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.hive.service.auth;
+
+import org.junit.BeforeClass;
+
+public class TestImproperTrustDomainAuthenticationHttp extends
TrustDomainAuthenticationTest {
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ initialize(HS2_TRANSPORT_MODE_HTTP, false);
+ }
+}
diff --git
a/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestTrustDomainAuthenticationBinary.java
b/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestTrustDomainAuthenticationBinary.java
new file mode 100644
index 0000000..8f6d0b5
--- /dev/null
+++
b/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestTrustDomainAuthenticationBinary.java
@@ -0,0 +1,28 @@
+/*
+ * 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.hive.service.auth;
+
+import org.junit.BeforeClass;
+
+public class TestTrustDomainAuthenticationBinary extends
TrustDomainAuthenticationTest {
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ initialize(HS2_TRANSPORT_MODE_BINARY, true);
+ }
+}
diff --git
a/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestTrustDomainAuthenticationHttp.java
b/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestTrustDomainAuthenticationHttp.java
new file mode 100644
index 0000000..50b195a
--- /dev/null
+++
b/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TestTrustDomainAuthenticationHttp.java
@@ -0,0 +1,28 @@
+/*
+ * 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.hive.service.auth;
+
+import org.junit.BeforeClass;
+
+public class TestTrustDomainAuthenticationHttp extends
TrustDomainAuthenticationTest {
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ initialize(HS2_TRANSPORT_MODE_HTTP, true);
+ }
+}
diff --git
a/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TrustDomainAuthenticationTest.java
b/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TrustDomainAuthenticationTest.java
new file mode 100644
index 0000000..3eba95c
--- /dev/null
+++
b/itests/hive-unit/src/test/java/org/apache/hive/service/auth/TrustDomainAuthenticationTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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.hive.service.auth;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hive.service.server.HiveServer2;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.sasl.AuthenticationException;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class TrustDomainAuthenticationTest {
+ private static final Logger LOG =
LoggerFactory.getLogger(TrustDomainAuthenticationTest.class);
+ private static HiveServer2 hiveserver2;
+ private static HiveConf hiveConf;
+ private static byte[] hiveConfBackup;
+ private static String correctUser = "hive";
+ private static String correctPassword = "passwd";
+ private static String wrongPassword = "wrong_password";
+ private static String wrongUser = "wrong_user";
+ static final String HS2_TRANSPORT_MODE_BINARY = "binary";
+ static final String HS2_TRANSPORT_MODE_HTTP = "http";
+ private static String hs2TransportMode;
+ private static boolean properTrustedDomain;
+
+ static void initialize(String transportMode, boolean useProperTrustedDomain)
throws Exception {
+ Assert.assertNotNull(transportMode);
+ Assert.assertTrue(transportMode.equals(HS2_TRANSPORT_MODE_HTTP) ||
+ transportMode.equals(HS2_TRANSPORT_MODE_BINARY));
+ hs2TransportMode = transportMode;
+ properTrustedDomain = useProperTrustedDomain;
+
+ hiveConf = new HiveConf();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ hiveConf.writeXml(baos);
+ baos.close();
+ hiveConfBackup = baos.toByteArray();
+ hiveConf.setVar(HiveConf.ConfVars.HIVE_SERVER2_TRANSPORT_MODE,
hs2TransportMode);
+ hiveConf.setVar(HiveConf.ConfVars.HIVE_SERVER2_AUTHENTICATION, "CUSTOM");
+
+ // These tests run locally and hence all connections are from localhost.
So, when we want to
+ // test whether trusted domain setting works, use "localhost". When we
want to test
+ // otherwise, use some string other than that. Other authentication tests
test empty trusted
+ // domain so that's not covered under these tests.
+ hiveConf.setVar(HiveConf.ConfVars.HIVE_SERVER2_TRUSTED_DOMAIN,
+ properTrustedDomain ? "localhost" : "no_such_domain");
+ hiveConf.setVar(HiveConf.ConfVars.HIVE_SERVER2_CUSTOM_AUTHENTICATION_CLASS,
+
"org.apache.hive.service.auth.TrustDomainAuthenticationTest$SimpleAuthenticationProviderImpl");
+ FileOutputStream fos = new FileOutputStream(new
File(hiveConf.getHiveSiteLocation().toURI()));
+ hiveConf.writeXml(fos);
+ fos.close();
+ hiveserver2 = new HiveServer2();
+ hiveserver2.init(hiveConf);
+ hiveserver2.start();
+ Thread.sleep(1000);
+ LOG.info("hiveServer2 start ......");
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ if(hiveConf != null && hiveConfBackup != null) {
+ FileOutputStream fos = new FileOutputStream(new
File(hiveConf.getHiveSiteLocation().toURI()));
+ fos.write(hiveConfBackup);
+ fos.close();
+ }
+ if (hiveserver2 != null) {
+ hiveserver2.stop();
+ hiveserver2 = null;
+ }
+ Thread.sleep(1000);
+ LOG.info("hiveServer2 stop ......");
+ }
+
+ // TODO: This test doesn't work since getRemoteHost returns IP address
instead of a host name
+ @Test
+ public void testTrustedDomainAuthentication() throws Exception {
+ String port = "10000";
+ String urlExtra = "";
+ if (hs2TransportMode.equals(HS2_TRANSPORT_MODE_HTTP)) {
+ port = "10001";
+ urlExtra = ";transportMode=http;httpPath=cliservice";
+ }
+
+ String url = "jdbc:hive2://localhost:" + port + "/default" + urlExtra;
+ Class.forName("org.apache.hive.jdbc.HiveDriver");
+
+ if (properTrustedDomain) {
+ testProperTrustedDomainAuthentication(url);
+ } else {
+ testImproperTrustedDomainAuthentication(url);
+ }
+ }
+
+ private void testProperTrustedDomainAuthentication(String url) throws
SQLException {
+ // When the connection is from a trusted domain any connection is
authentic irrespective of
+ // user and password
+ Connection connection = DriverManager.getConnection(url, correctUser,
correctPassword);
+ connection.close();
+
+ connection = DriverManager.getConnection(url, wrongUser, correctPassword);
+ connection.close();
+
+ connection = DriverManager.getConnection(url, wrongUser, wrongPassword);
+ connection.close();
+
+ connection = DriverManager.getConnection(url, correctUser, wrongPassword);
+ connection.close();
+ }
+
+ private void testImproperTrustedDomainAuthentication(String url) throws
Exception {
+ // When trusted domain doesn't match requests domain, only the connection
with correct user
+ // and password goes through.
+ Connection connection = DriverManager.getConnection(url, correctUser,
correctPassword);
+ connection.close();
+
+ String partErrorMessage = "Peer indicated failure: Error validating the
login";
+ if (hs2TransportMode.equals(HS2_TRANSPORT_MODE_HTTP)) {
+ partErrorMessage = "HTTP Response code: 401";
+ }
+
+ try (Connection conn = DriverManager.getConnection(url, wrongUser,
correctPassword)) {
+ Assert.fail("Expected Exception");
+ } catch (SQLException e) {
+ Assert.assertNotNull(e.getMessage());
+ Assert.assertTrue(e.getMessage(),
e.getMessage().contains(partErrorMessage));
+ }
+
+ try (Connection conn = DriverManager.getConnection(url, wrongUser,
wrongPassword)) {
+ Assert.fail("Expected Exception");
+ } catch (SQLException e) {
+ Assert.assertNotNull(e.getMessage());
+ Assert.assertTrue(e.getMessage(),
e.getMessage().contains(partErrorMessage));
+ }
+
+ try (Connection conn = DriverManager.getConnection(url, correctUser,
wrongPassword)) {
+ Assert.fail("Expected Exception");
+ } catch (SQLException e) {
+ Assert.assertNotNull(e.getMessage());
+ Assert.assertTrue(e.getMessage(),
e.getMessage().contains(partErrorMessage));
+ }
+ }
+
+ public static class SimpleAuthenticationProviderImpl implements
PasswdAuthenticationProvider {
+
+ private Map<String, String> userMap = new HashMap<String, String>();
+
+ public SimpleAuthenticationProviderImpl() {
+ init();
+ }
+
+ private void init(){
+ userMap.put(correctUser, correctPassword);
+ }
+
+ @Override
+ public void Authenticate(String user, String password) throws
AuthenticationException {
+
+ if(!userMap.containsKey(user)){
+ throw new AuthenticationException("Invalid user : "+user);
+ }
+ if(!userMap.get(user).equals(password)){
+ throw new AuthenticationException("Invalid passwd : "+password);
+ }
+ }
+ }
+}
diff --git a/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java
b/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java
index f5f6d49..e07cd7e 100644
--- a/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java
+++ b/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java
@@ -161,6 +161,11 @@ public class HiveAuthFactory {
} else {
throw new LoginException("Unsupported authentication type " +
authTypeStr);
}
+
+ String trustedDomain = HiveConf.getVar(conf,
ConfVars.HIVE_SERVER2_TRUSTED_DOMAIN).trim();
+ if (!trustedDomain.isEmpty()) {
+ transportFactory =
PlainSaslHelper.getDualPlainTransportFactory(transportFactory, trustedDomain);
+ }
return transportFactory;
}
diff --git a/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java
b/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java
index 13a1a38..0742311 100644
--- a/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java
+++ b/service/src/java/org/apache/hive/service/auth/PlainSaslHelper.java
@@ -18,6 +18,7 @@
package org.apache.hive.service.auth;
import java.io.IOException;
+import java.net.InetAddress;
import java.security.Security;
import java.util.HashMap;
@@ -39,10 +40,14 @@ import org.apache.thrift.TProcessor;
import org.apache.thrift.TProcessorFactory;
import org.apache.thrift.transport.TSaslClientTransport;
import org.apache.thrift.transport.TSaslServerTransport;
+import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public final class PlainSaslHelper {
+ private static final Logger LOG =
LoggerFactory.getLogger(PlainSaslHelper.class);
public static TProcessorFactory getPlainProcessorFactory(ThriftCLIService
service) {
return new SQLPlainProcessorFactory(service);
@@ -65,16 +70,65 @@ public final class PlainSaslHelper {
return saslFactory;
}
+ static TTransportFactory getDualPlainTransportFactory(TTransportFactory
otherTrans,
+ String trustedDomain)
+ throws LoginException {
+ LOG.info("Created additional transport factory for skipping authentication
when client " +
+ "connection is from the same domain.");
+ return new DualSaslTransportFactory(otherTrans, trustedDomain);
+ }
+
public static TTransport getPlainTransport(String username, String password,
TTransport underlyingTransport) throws SaslException {
return new TSaslClientTransport("PLAIN", null, null, null, new
HashMap<String, String>(),
new PlainCallbackHandler(username, password), underlyingTransport);
}
+ // Return true if the remote host is from the trusted domain, i.e. host URL
has the same
+ // suffix as the trusted domain.
+ static public boolean isHostFromTrustedDomain(String remoteHost, String
trustedDomain) {
+ return remoteHost.endsWith(trustedDomain);
+ }
+
private PlainSaslHelper() {
throw new UnsupportedOperationException("Can't initialize class");
}
+ static final class DualSaslTransportFactory extends TTransportFactory {
+ TTransportFactory otherFactory;
+ TTransportFactory noAuthFactory;
+ String trustedDomain;
+
+ DualSaslTransportFactory(TTransportFactory otherFactory, String
trustedDomain)
+ throws LoginException {
+ this.noAuthFactory =
getPlainTransportFactory(AuthMethods.NONE.toString());
+ this.otherFactory = otherFactory;
+ this.trustedDomain = trustedDomain;
+ }
+
+ @Override
+ public TTransport getTransport(final TTransport trans) {
+ TSocket tSocket = null;
+ // Attempt to avoid authentication if only we can fetch the client IP
address and it
+ // happens to be from the same domain as the server.
+ if (trans instanceof TSocket) {
+ tSocket = (TSocket) trans;
+ } else if (trans instanceof TSaslServerTransport) {
+ TSaslServerTransport saslTrans = (TSaslServerTransport) trans;
+ tSocket = (TSocket)(saslTrans.getUnderlyingTransport());
+ }
+ String remoteHost = tSocket != null ?
+ tSocket.getSocket().getInetAddress().getCanonicalHostName() :
null;
+ if (remoteHost != null && isHostFromTrustedDomain(remoteHost,
trustedDomain)) {
+ LOG.info("No authentication performed because the connecting host " +
remoteHost + " is " +
+ "from the trusted domain " + trustedDomain);
+ return noAuthFactory.getTransport(trans);
+ }
+
+ return otherFactory.getTransport(trans);
+ }
+ }
+
public static final class PlainServerCallbackHandler implements
CallbackHandler {
private final AuthMethods authMethod;
diff --git
a/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java
b/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java
index ff8f268..292723e 100644
--- a/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java
+++ b/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java
@@ -52,6 +52,7 @@ import org.apache.hive.service.auth.HiveAuthFactory;
import org.apache.hive.service.auth.HttpAuthUtils;
import org.apache.hive.service.auth.HttpAuthenticationException;
import org.apache.hive.service.auth.PasswdAuthenticationProvider;
+import org.apache.hive.service.auth.PlainSaslHelper;
import org.apache.hive.service.auth.ldap.HttpEmptyAuthenticationException;
import org.apache.hive.service.cli.HiveSQLException;
import org.apache.hive.service.cli.session.SessionManager;
@@ -137,6 +138,9 @@ public class ThriftHttpServlet extends TServlet {
return;
}
}
+
+ clientIpAddress = request.getRemoteAddr();
+ LOG.debug("Client IP Address: " + clientIpAddress);
// If the cookie based authentication is already enabled, parse the
// request and validate the request cookies.
if (isCookieAuthEnabled) {
@@ -146,25 +150,42 @@ public class ThriftHttpServlet extends TServlet {
LOG.info("Could not validate cookie sent, will try to generate a new
cookie");
}
}
- // If the cookie based authentication is not enabled or the request does
- // not have a valid cookie, use the kerberos or password based
authentication
- // depending on the server setup.
+ // If the cookie based authentication is not enabled or the request does
not have a valid
+ // cookie, use authentication depending on the server setup.
if (clientUserName == null) {
- // For a kerberos setup
- if (isKerberosAuthMode(authType)) {
- String delegationToken =
request.getHeader(HIVE_DELEGATION_TOKEN_HEADER);
- // Each http request must have an Authorization header
- if ((delegationToken != null) && (!delegationToken.isEmpty())) {
- clientUserName = doTokenAuth(request, response);
- } else {
- clientUserName = doKerberosAuth(request);
+ String trustedDomain = HiveConf.getVar(hiveConf,
ConfVars.HIVE_SERVER2_TRUSTED_DOMAIN).trim();
+
+ // Skip authentication if the connection is from the trusted domain,
if specified.
+ // getRemoteHost may or may not return the FQDN of the remote host
depending upon the
+ // HTTP server configuration. So, force a reverse DNS lookup.
+ String remoteHostName =
+
InetAddress.getByName(request.getRemoteHost()).getCanonicalHostName();
+ if (!trustedDomain.isEmpty() &&
+ PlainSaslHelper.isHostFromTrustedDomain(remoteHostName,
trustedDomain)) {
+ LOG.info("No authentication performed because the connecting host "
+ remoteHostName +
+ " is from the trusted domain " + trustedDomain);
+ // In order to skip authentication, we use auth type NOSASL to be
consistent with the
+ // HiveAuthFactory defaults. In HTTP mode, it will also get us the
user name from the
+ // HTTP request header.
+ clientUserName = doPasswdAuth(request,
HiveAuthConstants.AuthTypes.NOSASL.getAuthName());
+ } else {
+ // For a kerberos setup
+ if (isKerberosAuthMode(authType)) {
+ String delegationToken =
request.getHeader(HIVE_DELEGATION_TOKEN_HEADER);
+ // Each http request must have an Authorization header
+ if ((delegationToken != null) && (!delegationToken.isEmpty())) {
+ clientUserName = doTokenAuth(request, response);
+ } else {
+ clientUserName = doKerberosAuth(request);
+ }
+ }
+ // For password based authentication
+ else {
+ clientUserName = doPasswdAuth(request, authType);
}
- }
- // For password based authentication
- else {
- clientUserName = doPasswdAuth(request, authType);
}
}
+ assert (clientUserName != null);
LOG.debug("Client username: " + clientUserName);
// Set the thread local username to be used for doAs if true
@@ -176,8 +197,6 @@ public class ThriftHttpServlet extends TServlet {
SessionManager.setProxyUserName(doAsQueryParam);
}
- clientIpAddress = request.getRemoteAddr();
- LOG.debug("Client IP Address: " + clientIpAddress);
// Set the thread local ip address
SessionManager.setIpAddress(clientIpAddress);