Created on 12-08-2016 06:26 PM - edited on 12-09-2021 11:01 PM by VidyaSargur
This article applies to HDP 2.5.x and below. For HDP 2.6, please check new article.
Zeppelin can be configured to leverage an organization's Active Directory infrastructure for user authentication. By doing this, the existing Active Directory users can login to Zeppelin UI using their Active Directory credentials. This article discuss how to configure this kind of setup.
HDP 2.5 cluster / Sandbox
- I'm using HDP 2.5 Sandbox on VirtualBox. Get one from here !
Ambari 2.4+
- I'm using Ambari 2.4.0.0 which comes with HDP 2.5 Sandbox
'Zeppelin Notebook' Service installed in Ambari
- With HDP 2.5 Sandbox, it will be Zeppelin version 0.6.0
- If you don't have Zeppelin installed, it can be installed via 'Add Service' option in Ambari
Active Directory
- I'm using Active Directory 2012 R2 version
- Make sure that you have 'working' Active Directory details handy like URI, bind DN/password, search base etc.
1. From Ambari Dashboard, navigate to Zeppelin Notebook > Configs > Advanced zeppelin-config section.
2. Locate & set property "zeppelin.anonymous.allowed=false". By default, this is set to true so that any user can login to Zeppelin UI as anonymous user.
3. On the same Ambari page, navigate to next section called "Advanced zeppelin-env".
4. Locate a property called "shiro_ini_content". It contains an Apache Shiro configuration which Zeppelin uses to perform LDAP/AD authentication and authorization. Make the following changes to configure Zeppelin for Active Directory:
activeDirectoryRealm = org.apache.zeppelin.server.ActiveDirectoryGroupRealm activeDirectoryRealm.systemUsername = cn=ldap-reader,ou=ServiceUsers,dc=lab,dc=hortonworks,dc=net activeDirectoryRealm.systemPassword = badPassword #activeDirectoryRealm.hadoopSecurityCredentialPath = jceks://file/etc/zeppelin/conf/zeppelin.jceks activeDirectoryRealm.searchBase = dc=lab,dc=hortonworks,dc=net activeDirectoryRealm.url = ldap://ad.example.net:389 activeDirectoryRealm.authorizationCachingEnabled = false
Another working Shiro configuration could be:
contextFactory = org.apache.shiro.realm.ldap.JndiLdapContextFactory contextFactory.url = ldap://ad.example.net:389 contextFactory.systemUsername = cn=ldap-reader,ou=ServiceUsers,dc=lab,dc=hortonworks,dc=net contextFactory.systemPassword = badPassword contextFactory.authenticationMechanism = SIMPLE activeDirectoryRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm activeDirectoryRealm.ldapContextFactory = $contextFactory activeDirectoryRealm.searchBase = dc=lab,dc=hortonworks,dc=net
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager securityManager.sessionManager = $sessionManager securityManager.realms = $activeDirectoryRealm
The final shiro_ini_content should look like this:
[users] # List of users with their password allowed to access Zeppelin. # To use a different strategy (LDAP / Database / ...) check the shiro doc at http://shiro.apache.org/configuration.html#Configuration-INISections #admin = password1 #user1 = password2, role1, role2 #user2 = password3, role3 #user3 = password4, role2 # Sample LDAP configuration, for user Authentication, currently tested for single Realm [main] activeDirectoryRealm = org.apache.zeppelin.server.ActiveDirectoryGroupRealm activeDirectoryRealm.systemUsername = cn=ldap-reader,ou=ServiceUsers,dc=lab,dc=hortonworks,dc=net activeDirectoryRealm.systemPassword = badPassword #activeDirectoryRealm.hadoopSecurityCredentialPath = jceks://user/zeppelin/conf/zeppelin.jceks activeDirectoryRealm.searchBase = dc=lab,dc=hortonworks,dc=net activeDirectoryRealm.url = ldap://ad.example.net:389 activeDirectoryRealm.authorizationCachingEnabled = false sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager securityManager.sessionManager = $sessionManager securityManager.realms = $activeDirectoryRealm # 86,400,000 milliseconds = 24 hour securityManager.sessionManager.globalSessionTimeout = 86400000 shiro.loginUrl = /api/login [urls] # anon means the access is anonymous. # authcBasic means Basic Auth Security # To enfore security, comment the line below and uncomment the next one /api/version = anon #/** = anon /** = authc
5. Save the configuration changes and restart Zeppelin Notebook service.
6. If something goes wrong, check Troubleshooting section at the end.
1. Once Zeppelin service is restarted, open the Zeppelin UI in a new browser tab by typing http://zeppelin-hostname:9995. Since I'm using HDP 2.5 Sandbox, for me it is http://127.0.0.1:9995
2. Click on "Login" button in the top right corner.
3. Specify any valid Active Directory username and password in the Login window. Make sure to provide the fully qualified user name like "ad-username@AD.DOMAIN.COM", a short username like "ad-username" will give an error (check next section).
If everything goes fine, user will be able to login using their Active Directory credentials. At the same time, the log file will show a success message like this:
WARN [2016-11-26 01:06:27,563] ({qtp627185331-13 - /api/login} LoginRestApi.java[postLogin]:111) - {"status":"OK","message":"","body":{"principal":"hr1@EXAMPLE.NET","ticket":"cc231146-293a-4f5e-8045-aea4b0fea37a","roles":"[]"}}
In case of any error during service restart after configuration changes, most probably it will be due to incorrect / incomplete configuration. Zeppelin log file can be found at /var/log/zeppelin/zeppelin-zeppelin-sandbox.hortonworks.com.log location on the Zeppelin host. Please check log file for error(s).
1. Incorrect Realm class name
- Upon restart, Zeppelin service will die and while there will be no logs in /var/log/zeppelin/zeppelin-zeppelin-sandbox.hortonworks.com.log, but the /var/log/zeppelin/zeppelin-zeppelin-sandbox.hortonworks.com.out will have an error saying ClassNotFoundException for Realm class.
- Make sure that Realm class name is spelled correctly. Valid realm class names are:
org.apache.zeppelin.server.ActiveDirectoryGroupRealm
org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
Please note that based on the Realm class used, the Shiro configuration properties might change slightly. So check the relevant documentation before using.
2. "The username and password that you entered don't match."
- At the time of login, if user get this message in UI then check the log file. If it has a line,
"Caused by: javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903C8, comment: AcceptSecurityContext error, data 52e, v2580^@]"
This means that username or password specified at Login window is not correct. Make sure to use the fully qualified username with domain name and right password.
Created on 12-08-2016 06:30 PM
Nice Job! I did a similar article with a zeppelin + livy + AD/LDAP in case you want to check out livy steps:
Created on 12-09-2016 07:22 AM
Thanks @azeltov. I did check that one before writing this. Wanted to address the pain points and common issues that our users are facing around this. Cheers !
Created on 01-18-2017 04:44 PM
Hi Vipin,
I need a clarification regarding roles. We are using AD for authentication and all users are getting access to zeppelin.How can I restrict access to specific users or specific groups using roles.
Please help. Thanks in advance.
Regards,
Sharan
Created on 05-28-2017 11:48 AM
Hello @Sharan Teja Malyala
What you are looking for is rolesByGroup feature available in HDP 2.6. Please check this article to know how to use that.
Hope this helps !
Created on 09-06-2017 10:57 AM
Hi Vipin,
I tried with same configurations(With HDP 2.5.5,Zeppelin version 0.6.0.2.5.5.0-157)but I got the below exception.
ERROR LoginRestApi.java[postLogin]:103) - Exception in login:
org.apache.shiro.authc.AuthenticationException: LDAP naming error while attempting to authenticate user.
at org.apache.shiro.realm.ldap.AbstractLdapRealm.doGetAuthenticationInfo(AbstractLdapRealm.java:197)
Caused by: javax.naming.CommunicationException: simple bind failed: <server>:636 [Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]
Advanced zeppelin-config:
zeppelin.anonymous.allowed=false
Advanced zeppelin-env:
shiro_ini_content:
[users]
# List of users with their password allowed to access Zeppelin.
# To use a different strategy (LDAP / Database / ...) check the shiro doc at http://shiro.apache.org/configuration.html#Configuration-INISections
#admin = password1
#user1 = password2, role1, role2
#user2 = password3, role3
#user3 = password4, role2
# Sample LDAP configuration, for user Authentication, currently tested for single Realm
[main]
activeDirectoryRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
activeDirectoryRealm.systemUsername = CN=<systemusername>,OU=<VALUE>,OU=<VALUE>,DC=<VALUE>,DC=<VALUE>,DC=<VALUE>
activeDirectoryRealm.systemPassword = <systempassword>
#activeDirectoryRealm.hadoopSecurityCredentialPath= jceks://user/zeppelin/conf/zeppelin.jceks
activeDirectoryRealm.searchBase = OU=<VALUE>,OU=<VALUE>,DC=<VALUE>,DC=<VALUE>,DC=<VALUE>
activeDirectoryRealm.url = ldaps://<VALUE>:636
activeDirectoryRealm.authorizationCachingEnabled = false
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
securityManager.realms = $activeDirectoryRealm
# 86,400,000 milliseconds = 24 hour
securityManager.sessionManager.globalSessionTimeout = 86400000
shiro.loginUrl = /api/login
[roles]
[urls]
/api/version = anon
#/** = anon
/** = authc
Created on 09-06-2017 12:53 PM
Hi @Pooja Kamle,
Caused by: javax.naming.CommunicationException: simple bind failed: <server>:636 [Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]
The issue is Active Directory SSL certificate had not been imported into the "cacerts" keystore used by the Java Runtime Environment (JRE) running the Zeppelin services.
Could you please ensure you have imported the AD SSL certificate into the cacerts keystore on the node running Zeppelin.
Created on 09-06-2017 01:20 PM
Hi @Pravin Bhagade,
This solved my issue. I had not imported the SSL certificate in the keystore. After doing this, the AD authentication works.
Thank you so much.
Created on 11-30-2017 02:01 PM
Came to this page when troubleshooting...
When a user opened a notebook this message would appear in the logs, they were still able to view notebooks in our configuration.
ERROR [2017-11-30 00:03:36,714] ({qtp431687835-71} GetUserList.java[getUserList]:107) - Error retrieving User list from ActiveDirectory Realm javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C09042F, comment: AcceptSecurityCo ntext error, data 52e, v2580^@]
Found a good tip here
Conclusion is that when activeDirectoryRealm.principalSuffix is used activeDirectoryRealm.systemUsername should just be the simple username (e.g. ldap-reader) , rather than the fully distinguished name as shown in this setup guide.
Also I found Credential Providers (jceks) aren't too hard to work with once you know about hadoop credential
Usage: hadoop credential [generic options] [--help] [create <alias> [-provider provider-path]] [delete <alias> [-f] [-provider provider-path]] [list [-provider provider-path]]
Created on 10-19-2018 03:30 PM
Hi Vipin ,
Thanks for sharing the steps , I landed up here finding ways to troubleshoot during configuration , I have configured the shiro.ini file (attached) but I am getting the below error.
Please let me know if you can help me on this. Any help would be appreciated.
I am trying to authenticate AD using PAM Ldap with Zeppelin.
ERROR [2018-10-19 13:36:34,315] ({qtp2059904228-153} LoginRestApi.java[proceedToLogin]:172) - Exception in login: org.apache.shiro.authc.AuthenticationException: Authentication failed for token submission [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false]. Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException). at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:214) at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106) at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:270) at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:256) <br>
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.jvnet.libpam.impl.PAMLibrary$pam_conv at org.jvnet.libpam.PAM.<init>(PAM.java:73) at org.apache.zeppelin.realm.PamRealm.doGetAuthenticationInfo(PamRealm.java:71) at org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:568) at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:180) at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:267) at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198) ... 66 more <br>
Created on 11-17-2021 07:20 AM - edited 11-17-2021 07:22 AM
Please try the below steps, this can happen if /tmp mount point is mounted with noexec option...
- Create a new directory under any directory(ex /data/tmp) with exec permission and to test provide 777 permissions for newly created dir. - Update the config in zeppelin config as below and restart the zeppelin. CM UI --> Zeppelin --> Config --> "Zeppelin Server Advanced Configuration Snippet (Safety Valve) for zeppelin-conf/zeppelin-env.sh" --> Add export ZEPPELIN_JAVA_OPTS="-Djava.io.tmpdir=<directory name>" example: export ZEPPELIN_JAVA_OPTS="-Djava.io.tmpdir=/data/tmp" - Save changes and restart zeppelin server and verify the login