You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by pr...@apache.org on 2016/08/25 09:18:16 UTC

zeppelin git commit: [ZEPPELIN-530] Added changes for Credential Provider, using hadoop commons Credential apis

Repository: zeppelin
Updated Branches:
  refs/heads/master ce5618820 -> 5ac3faeba


[ZEPPELIN-530] Added changes for Credential Provider, using hadoop commons Credential apis

### What is this PR for?
This is the first step in order to ensure clear text passwords are not stored in the configuration files. To start with this PR will take care of getting AD system password from the .jceks file, configured by the user specified in the shiro.ini file. Going forward the same keystore can be used to read passwords for other systems as well.

If the hadoopSecurityCredentialPath path is present and not empty in the shiro.ini, then the password is read from the keystore file and it need not be stored inside the shiro.ini file.

### What type of PR is it?
[ Improvement]

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

### How should this be tested?
Create a keystore file using the hadoop credential commandline, for this the hadoop commons should be in the classpath

`hadoop credential create activeDirectoryRealm.systempassword -provider jceks://file/user/zeppelin/conf/zeppelin.jceks`

Change the following values in the Shiro.ini file, and uncomment the line:

`activeDirectoryRealm.hadoopSecurityCredentialPath = jceks://file/user/zeppelin/conf/zeppelin.jceks`

### Questions:
* Does the licenses files need update?
No
* Is there breaking changes for older versions?
No. This is an additional option.
* Does this needs documentation?
Yes

### Tasks
* Documentation

Author: Rohit Choudhary <rc...@gmail.com>

Closes #1315 from rconline/ZEPPELIN-530 and squashes the following commits:

2156675 [Rohit Choudhary] use latest instead of 0.7.0-SNAPSHOT
40bb290 [Rohit Choudhary] remove extra line
24c6852 [Rohit Choudhary] add documentation
cfecf74 [Rohit Choudhary] [ZEPPELIN-530] Added changes for Credential Provider, using hadoop commons and credential api's.


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

Branch: refs/heads/master
Commit: 5ac3faeba4877feefd79d72b15aa49d56afc0aa0
Parents: ce56188
Author: Rohit Choudhary <rc...@gmail.com>
Authored: Tue Aug 23 14:14:33 2016 +0530
Committer: Prabhjyot Singh <pr...@gmail.com>
Committed: Thu Aug 25 14:47:59 2016 +0530

----------------------------------------------------------------------
 conf/shiro.ini                                  |  3 ++
 docs/security/shiroauthentication.md            | 30 ++++++++++-
 zeppelin-server/pom.xml                         | 56 ++++++++++++++++++++
 .../server/ActiveDirectoryGroupRealm.java       | 37 ++++++++++++-
 4 files changed, 123 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/5ac3faeb/conf/shiro.ini
----------------------------------------------------------------------
diff --git a/conf/shiro.ini b/conf/shiro.ini
index 75a3fb9..0562ba2 100644
--- a/conf/shiro.ini
+++ b/conf/shiro.ini
@@ -28,7 +28,10 @@ user3 = password4, role2
 ### A sample for configuring Active Directory Realm
 #activeDirectoryRealm = org.apache.zeppelin.server.ActiveDirectoryGroupRealm
 #activeDirectoryRealm.systemUsername = userNameA
+
+#use either systemPassword or hadoopSecurityCredentialPath, more details in http://zeppelin.apache.org/docs/latest/security/shiroauthentication.html
 #activeDirectoryRealm.systemPassword = passwordA
+#activeDirectoryRealm.hadoopSecurityCredentialPath = jceks://file/user/zeppelin/zeppelin.jceks
 #activeDirectoryRealm.searchBase = CN=Users,DC=SOME_GROUP,DC=COMPANY,DC=COM
 #activeDirectoryRealm.url = ldap://ldap.test.com:389
 #activeDirectoryRealm.groupRolesMap = "CN=admin,OU=groups,DC=SOME_GROUP,DC=COMPANY,DC=COM":"admin","CN=finance,OU=groups,DC=SOME_GROUP,DC=COMPANY,DC=COM":"finance","CN=hr,OU=groups,DC=SOME_GROUP,DC=COMPANY,DC=COM":"hr"

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/5ac3faeb/docs/security/shiroauthentication.md
----------------------------------------------------------------------
diff --git a/docs/security/shiroauthentication.md b/docs/security/shiroauthentication.md
index 65a116d..969e61e 100644
--- a/docs/security/shiroauthentication.md
+++ b/docs/security/shiroauthentication.md
@@ -112,10 +112,36 @@ To learn more about Apache Shiro Realm, please check [this documentation](http:/
 We also provide community custom Realms.
 
 ### Active Directory
-TBD
+
+```
+activeDirectoryRealm = org.apache.zeppelin.server.ActiveDirectoryGroupRealm
+activeDirectoryRealm.systemUsername = userNameA
+activeDirectoryRealm.systemPassword = passwordA
+activeDirectoryRealm.hadoopSecurityCredentialPath = jceks://file/user/zeppelin/conf/zeppelin.jceks
+activeDirectoryRealm.searchBase = CN=Users,DC=SOME_GROUP,DC=COMPANY,DC=COM
+activeDirectoryRealm.url = ldap://ldap.test.com:389
+activeDirectoryRealm.groupRolesMap = "CN=aGroupName,OU=groups,DC=SOME_GROUP,DC=COMPANY,DC=COM":"group1"
+activeDirectoryRealm.authorizationCachingEnabled = false
+```
+
+
+Also instead of specifying systemPassword in clear text in shiro.ini administrator can choose to specify the same in "hadoop credential".
+Create a keystore file using the hadoop credential commandline, for this the hadoop commons should be in the classpath
+`hadoop credential create activeDirectoryRealm.systempassword -provider jceks://file/user/zeppelin/conf/zeppelin.jceks`
+
+Change the following values in the Shiro.ini file, and uncomment the line:
+`activeDirectoryRealm.hadoopSecurityCredentialPath = jceks://file/user/zeppelin/conf/zeppelin.jceks`
 
 ### LDAP
-TBD
+
+```
+ldapRealm = org.apache.zeppelin.server.LdapGroupRealm
+# search base for ldap groups (only relevant for LdapGroupRealm):
+ldapRealm.contextFactory.environment[ldap.searchBase] = dc=COMPANY,dc=COM
+ldapRealm.contextFactory.url = ldap://ldap.test.com:389
+ldapRealm.userDnTemplate = uid={0},ou=Users,dc=COMPANY,dc=COM
+ldapRealm.contextFactory.authenticationMechanism = SIMPLE
+```
 
 ### ZeppelinHub
 [ZeppelinHub](https://www.zeppelinhub.com) is a service that synchronize your Apache Zeppelin notebooks and enables you to collaborate easily.

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/5ac3faeb/zeppelin-server/pom.xml
----------------------------------------------------------------------
diff --git a/zeppelin-server/pom.xml b/zeppelin-server/pom.xml
index 64e06b2..eac96f0 100644
--- a/zeppelin-server/pom.xml
+++ b/zeppelin-server/pom.xml
@@ -35,6 +35,7 @@
   <properties>
     <cxf.version>2.7.7</cxf.version>
     <commons.httpclient.version>4.3.6</commons.httpclient.version>
+    <hadoop-common.version>2.6.0</hadoop-common.version>
   </properties>
 
   <dependencyManagement>
@@ -206,6 +207,61 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <version>${hadoop-common.version}</version>
+      <exclusions>
+        <exclusion>
+          <groupId>com.sun.jersey</groupId>
+          <artifactId>jersey-core</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jersey</groupId>
+          <artifactId>jersey-json</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.sun.jersey</groupId>
+          <artifactId>jersey-server</artifactId>
+        </exclusion>
+
+
+        <exclusion>
+          <groupId>javax.servlet</groupId>
+          <artifactId>servlet-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.apache.avro</groupId>
+          <artifactId>avro</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.apache.jackrabbit</groupId>
+          <artifactId>jackrabbit-webdav</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>io.netty</groupId>
+          <artifactId>netty</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>commons-httpclient</groupId>
+          <artifactId>commons-httpclient</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.apache.zookeeper</groupId>
+          <artifactId>zookeeper</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.eclipse.jgit</groupId>
+          <artifactId>org.eclipse.jgit</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.jcraft</groupId>
+          <artifactId>jsch</artifactId>
+        </exclusion>
+
+      </exclusions>
+    </dependency>
+
+    <dependency>
       <groupId>org.quartz-scheduler</groupId>
       <artifactId>quartz</artifactId>
       <version>2.2.1</version>

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/5ac3faeb/zeppelin-server/src/main/java/org/apache/zeppelin/server/ActiveDirectoryGroupRealm.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ActiveDirectoryGroupRealm.java b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ActiveDirectoryGroupRealm.java
index cc868d7..556f404 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ActiveDirectoryGroupRealm.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ActiveDirectoryGroupRealm.java
@@ -16,6 +16,10 @@
  */
 package org.apache.zeppelin.server;
 
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.alias.CredentialProvider;
+import org.apache.hadoop.security.alias.CredentialProviderFactory;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
 import org.apache.shiro.authc.SimpleAuthenticationInfo;
@@ -55,6 +59,13 @@ public class ActiveDirectoryGroupRealm extends AbstractLdapRealm {
 
   private static final String ROLE_NAMES_DELIMETER = ",";
 
+  String KEYSTORE_PASS = "activeDirectoryRealm.systemPassword";
+  private String hadoopSecurityCredentialPath;
+
+  public void setHadoopSecurityCredentialPath(String hadoopSecurityCredentialPath) {
+    this.hadoopSecurityCredentialPath = hadoopSecurityCredentialPath;
+  }
+
     /*--------------------------------------------
     |    I N S T A N C E   V A R I A B L E S    |
     ============================================*/
@@ -91,13 +102,36 @@ public class ActiveDirectoryGroupRealm extends AbstractLdapRealm {
       defaultFactory.setSearchBase(this.searchBase);
       defaultFactory.setUrl(this.url);
       defaultFactory.setSystemUsername(this.systemUsername);
-      defaultFactory.setSystemPassword(this.systemPassword);
+      defaultFactory.setSystemPassword(getSystemPassword());
       this.ldapContextFactory = defaultFactory;
     }
 
     return this.ldapContextFactory;
   }
 
+  private String getSystemPassword() {
+    String password = "";
+    if (StringUtils.isEmpty(this.hadoopSecurityCredentialPath)) {
+      password = this.systemPassword;
+    } else {
+      try {
+        Configuration configuration = new Configuration();
+        configuration.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH,
+          this.hadoopSecurityCredentialPath);
+        CredentialProvider provider =
+          CredentialProviderFactory.getProviders(configuration).get(0);
+        CredentialProvider.CredentialEntry credEntry = provider.getCredentialEntry(
+            KEYSTORE_PASS);
+        if (credEntry != null) {
+          password = new String(credEntry.getCredential());
+        }
+      } catch (Exception e) {
+
+      }
+    }
+    return password;
+  }
+
   /**
    * Builds an {@link AuthenticationInfo} object by querying the active directory LDAP context for
    * the specified username.  This method binds to the LDAP server using the provided username
@@ -293,3 +327,4 @@ public class ActiveDirectoryGroupRealm extends AbstractLdapRealm {
   }
 
 }
+