Repository: zeppelin
Updated Branches:
  refs/heads/master 88c5c3ccd -> e3ba23a9a


[ZEPPELIN-2584]. Livy doesn't work under kerberos and ssl

### What is this PR for?
We found that Livy doesn't work under kerberos and ssl, this is due to a bug 
when constructing KerberosRestTemplate. This PR fix this issue.

### What type of PR is it?
[Bug Fix]

### Todos
* [ ] - Task

### What is the Jira issue?
* https://issues.apache.org/jira/browse/ZEPPELIN-2584

### How should this be tested?
Unfornatelly it is difficult to add system test, so I manually tested it in a 
secure cluster.

### Screenshots (if appropriate)

### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No

Author: root <r...@ctr-e133-1493418528701-48413-01-000004.hwx.site>

Closes #2367 from zjffdu/ZEPPELIN-2584 and squashes the following commits:

18b23dc [root] [ZEPPELIN-2584]. Livy doesn't work under kerberos and ssl


Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/e3ba23a9
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/e3ba23a9
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/e3ba23a9

Branch: refs/heads/master
Commit: e3ba23a9aa4909c7a8d3231e4d363771e0245b53
Parents: 88c5c3c
Author: root <r...@ctr-e133-1493418528701-48413-01-000004.hwx.site>
Authored: Fri May 26 08:44:09 2017 +0000
Committer: Jeff Zhang <zjf...@apache.org>
Committed: Thu Jun 1 15:17:21 2017 +0800

----------------------------------------------------------------------
 livy/pom.xml                                    | 18 -------
 .../zeppelin/livy/BaseLivyInterpreter.java      | 56 +++++++++++++++++---
 pom.xml                                         |  4 +-
 3 files changed, 52 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/e3ba23a9/livy/pom.xml
----------------------------------------------------------------------
diff --git a/livy/pom.xml b/livy/pom.xml
index 3c121fc..5f9dec7 100644
--- a/livy/pom.xml
+++ b/livy/pom.xml
@@ -37,14 +37,10 @@
   <properties>
     <!--library versions-->
     <commons.exec.version>1.3</commons.exec.version>
-    <httpcomponents.client.version>4.3.4</httpcomponents.client.version>
     <spring.web.version>4.3.0.RELEASE</spring.web.version>
     
<spring.security.kerberosclient>1.0.1.RELEASE</spring.security.kerberosclient>
 
     <!--test library versions-->
-    <achilles.version>3.2.4-Zeppelin</achilles.version>
-    <assertj.version>1.7.0</assertj.version>
-    <mockito.version>1.9.5</mockito.version>
     <livy.version>0.3.0</livy.version>
     <spark.version>2.1.0</spark.version>
     <hadoop.version>2.6.0</hadoop.version>
@@ -80,7 +76,6 @@
     <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
-      <version>${httpcomponents.client.version}</version>
     </dependency>
 
     <dependency>
@@ -107,19 +102,6 @@
     </dependency>
 
     <dependency>
-      <groupId>org.assertj</groupId>
-      <artifactId>assertj-core</artifactId>
-      <version>${assertj.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <version>${mockito.version}</version>
-      <scope>test</scope>
-    </dependency>
-
-    <dependency>
       <groupId>com.cloudera.livy</groupId>
       <artifactId>livy-integration-test</artifactId>
       <version>${livy.version}</version>

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/e3ba23a9/livy/src/main/java/org/apache/zeppelin/livy/BaseLivyInterpreter.java
----------------------------------------------------------------------
diff --git 
a/livy/src/main/java/org/apache/zeppelin/livy/BaseLivyInterpreter.java 
b/livy/src/main/java/org/apache/zeppelin/livy/BaseLivyInterpreter.java
index b52ba16..fcb7e9d 100644
--- a/livy/src/main/java/org/apache/zeppelin/livy/BaseLivyInterpreter.java
+++ b/livy/src/main/java/org/apache/zeppelin/livy/BaseLivyInterpreter.java
@@ -21,9 +21,20 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.annotations.SerializedName;
 import org.apache.commons.lang.StringUtils;
+import org.apache.http.auth.AuthSchemeProvider;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.CredentialsProvider;
 import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.AuthSchemes;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.http.conn.ssl.SSLContexts;
+import org.apache.http.impl.auth.SPNegoSchemeFactory;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.zeppelin.interpreter.*;
@@ -38,11 +49,11 @@ import 
org.springframework.security.kerberos.client.KerberosRestTemplate;
 import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.client.RestClientException;
 import org.springframework.web.client.RestTemplate;
-
 import javax.net.ssl.SSLContext;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.security.KeyStore;
+import java.security.Principal;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -52,7 +63,6 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 
-
 /**
  * Base class for livy interpreters.
  */
@@ -407,6 +417,11 @@ public abstract class BaseLivyInterpreter extends 
Interpreter {
 
 
   private RestTemplate createRestTemplate() {
+    String keytabLocation = property.getProperty("zeppelin.livy.keytab");
+    String principal = property.getProperty("zeppelin.livy.principal");
+    boolean isSpnegoEnabled = StringUtils.isNotEmpty(keytabLocation) &&
+        StringUtils.isNotEmpty(principal);
+
     HttpClient httpClient = null;
     if (livyURL.startsWith("https:")) {
       String keystoreFile = 
property.getProperty("zeppelin.livy.ssl.trustStore");
@@ -427,7 +442,37 @@ public abstract class BaseLivyInterpreter extends 
Interpreter {
             .loadTrustMaterial(trustStore)
             .build();
         SSLConnectionSocketFactory csf = new 
SSLConnectionSocketFactory(sslContext);
-        httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
+        HttpClientBuilder httpClientBuilder = 
HttpClients.custom().setSSLSocketFactory(csf);
+        RequestConfig reqConfig = new RequestConfig() {
+          @Override
+          public boolean isAuthenticationEnabled() {
+            return true;
+          }
+        };
+        httpClientBuilder.setDefaultRequestConfig(reqConfig);
+        Credentials credentials = new Credentials() {
+          @Override
+          public String getPassword() {
+            return null;
+          }
+
+          @Override
+          public Principal getUserPrincipal() {
+            return null;
+          }
+        };
+        CredentialsProvider credsProvider = new BasicCredentialsProvider();
+        credsProvider.setCredentials(AuthScope.ANY, credentials);
+        httpClientBuilder.setDefaultCredentialsProvider(credsProvider);
+        if (isSpnegoEnabled) {
+          Registry<AuthSchemeProvider> authSchemeProviderRegistry =
+              RegistryBuilder.<AuthSchemeProvider>create()
+                  .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory())
+                  .build();
+          
httpClientBuilder.setDefaultAuthSchemeRegistry(authSchemeProviderRegistry);
+        }
+
+        httpClient = httpClientBuilder.build();
       } catch (Exception e) {
         throw new RuntimeException("Failed to create SSL HttpClient", e);
       } finally {
@@ -441,9 +486,8 @@ public abstract class BaseLivyInterpreter extends 
Interpreter {
       }
     }
 
-    String keytabLocation = property.getProperty("zeppelin.livy.keytab");
-    String principal = property.getProperty("zeppelin.livy.principal");
-    if (StringUtils.isNotEmpty(keytabLocation) && 
StringUtils.isNotEmpty(principal)) {
+
+    if (isSpnegoEnabled) {
       if (httpClient == null) {
         return new KerberosRestTemplate(keytabLocation, principal);
       } else {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/e3ba23a9/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 87af323..9232b9e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -96,8 +96,8 @@
     <gson-extras.version>0.2.1</gson-extras.version>
     <guava.version>15.0</guava.version>
     <jetty.version>9.2.15.v20160210</jetty.version>
-    <httpcomponents.core.version>4.3.3</httpcomponents.core.version>
-    <httpcomponents.client.version>4.3.6</httpcomponents.client.version>
+    <httpcomponents.core.version>4.4.1</httpcomponents.core.version>
+    <httpcomponents.client.version>4.5.1</httpcomponents.client.version>
     
<httpcomponents.asyncclient.version>4.0.2</httpcomponents.asyncclient.version>
     <commons.lang.version>2.5</commons.lang.version>
     <commons.configuration.version>1.9</commons.configuration.version>

Reply via email to