[GH-ISSUE #1123] [INTEGRATION] Apache Zeppelin and CLoudera Hue #400

Open
opened 2026-02-27 08:17:05 +03:00 by kerem · 9 comments
Owner

Originally created by @DevId-E on GitHub (Mar 6, 2025).
Original GitHub issue: https://github.com/lldap/lldap/issues/1123

Checklist

  • Check if there is already an example config for it.
  • Try to figure out the configuration values for the new service yourself.
    • You can use other example configs for inspiration.
    • If you're having trouble, you can ask on Discord or create an issue.
    • If you succeed, make sure to contribute an example configuration, or a configuration guide.
  • If you hit a block because of an unimplemented feature, create an issue.

Description of the service
Zeppelin and Hue work on top of hadoop/spark.

What you've tried
Sample config from hue and zeppelin were put in place.

What's not working
Groups can not be found.

Originally created by @DevId-E on GitHub (Mar 6, 2025). Original GitHub issue: https://github.com/lldap/lldap/issues/1123 **Checklist** - [x] Check if there is already an [example config](https://github.com/lldap/lldap/tree/main/example_configs) for it. - [x] Try to figure out the configuration values for the new service yourself. - You can use other example configs for inspiration. - If you're having trouble, you can ask on [Discord](https://discord.gg/h5PEdRMNyP) or create an issue. - If you succeed, make sure to contribute an example configuration, or a configuration guide. - If you hit a block because of an unimplemented feature, create an issue. **Description of the service** Zeppelin and Hue work on top of hadoop/spark. **What you've tried** Sample config from hue and zeppelin were put in place. **What's not working** Groups can not be found.
Author
Owner

@nitnelave commented on GitHub (Mar 6, 2025):

Can you turn on verbose logging in LLDAP and post the logs? I should really make that part of the issue template.

That'll show what the query is, and the response. We can then see if the problem is on LLDAP side, in the config, or in the service parsing the response.

<!-- gh-comment-id:2705136444 --> @nitnelave commented on GitHub (Mar 6, 2025): Can you turn on verbose logging in LLDAP and post the logs? I should really make that part of the issue template. That'll show what the query is, and the response. We can then see if the problem is on LLDAP side, in the config, or in the service parsing the response.
Author
Owner

@DevId-E commented on GitHub (Mar 7, 2025):

Let's start with Zeppelin, zeppelin uses shiro for authentication.

Using basic ldap settings works, but as groups are not mapped, zeppelin is not really usable.

ldapRealm = org.apache.zeppelin.realm.LdapGroupRealm
## search base for ldap groups (only relevant for LdapGroupRealm):
ldapRealm.contextFactory.environment[ldap.searchBase] = dc=ddw,dc=local
ldapRealm.contextFactory.url = ldap://lldap:3890
ldapRealm.userDnTemplate = uid={0},ou=people,dc=ddw,dc=local
ldapRealm.contextFactory.authenticationMechanism = simple
ldapRealm.contextFactory.systemUsername = uid=guest,ou=people,dc=ddw,dc=local
ldapRealm.contextFactory.systemPassword = guest-password

When changing to the advanced configuration, no login is possible.

ldapRealm=org.apache.zeppelin.realm.LdapRealm

ldapRealm.contextFactory.authenticationMechanism = simple
ldapRealm.contextFactory.url = ldap://lldap:3890
ldapRealm.userDnTemplate = uid={0},ou=people,dc=ddw,dc=local
# Ability to set ldap paging Size if needed default is 100
ldapRealm.pagingSize = 200
ldapRealm.authorizationEnabled = true
ldapRealm.searchBase = dc=ddw,dc=local
ldapRealm.userSearchBase = dc=ddw,dc=local
ldapRealm.groupSearchBase = ou=groups,dc=ddw,dc=local
ldapRealm.groupObjectClass = groupOfUniqueNames
# Allow userSearchAttribute to be customized
# If userSearchAttributeName was configured, Zeppelin would use userObjectClass and userSearchAttributeName to search for an actual user DN
# Otherwise, memberAttributeValueTemplate would be used to construct the user DN.
ldapRealm.userSearchAttributeName = uid
ldapRealm.memberAttribute = memberOf
# force usernames returned from ldap to lowercase useful for AD
ldapRealm.userLowerCase = false
# ability set searchScopes subtree (default), one, base
ldapRealm.userSearchScope = subtree;
ldapRealm.groupSearchScope = subtree;
ldapRealm.memberAttributeValueTemplate = cn={0},ou=people,dc=ddw,dc=local
ldapRealm.contextFactory.systemUsername = uid=guest,ou=people,dc=ddw,dc=local
ldapRealm.contextFactory.systemPassword = guest-password
# enable support for nested groups using the LDAP_MATCHING_RULE_IN_CHAIN operator
ldapRealm.groupSearchEnableMatchingRuleInChain = true
# optional mapping from physical groups to logical application roles
ldapRealm.rolesByGroup = ddw: admin_role, LDN_USERS: user_role, NYK_USERS: user_role, HKG_USERS: user_role, GLOBAL_ADMIN: admin_role
# optional list of roles that are allowed to authenticate. Incase not present all groups are allowed to authenticate (login).
# This changes nothing for url specific permissions that will continue to work as specified in [urls].
ldapRealm.allowedRolesForAuthentication = admin_role,user_role
ldapRealm.permissionsByRole = user_role: "*:ToDoItemsJdo:*:*, *:ToDoItem:*:*", admin_role: "*"
securityManager.sessionManager = $sessionManager
securityManager.realms = $ldapRealm

When logging in, zeppelin complains about:

zeppelin-1  |  WARN [2025-03-07 18:51:43,898] ({qtp96406857-24} AbstractAuthenticator.java[authenticate]:216) - Authentication failed for token submission [org.apache.shiro.authc.UsernamePasswordToken - null, rememberMe=false (10.10.10.1)].  Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException).
zeppelin-1  | org.apache.shiro.ldap.UnsupportedAuthenticationMechanismException: Unsupported configured authentication mechanism
zeppelin-1  | Caused by: javax.naming.AuthenticationNotSupportedException: [LDAP: error code 48 - Anonymous bind not allowed]

it seems the guest-user cannot authenticate.

https://zeppelin.apache.org/docs/latest/setup/security/shiro_authentication.html

lldap.log

<!-- gh-comment-id:2707192298 --> @DevId-E commented on GitHub (Mar 7, 2025): Let's start with Zeppelin, zeppelin uses shiro for authentication. Using basic ldap settings works, but as groups are not mapped, zeppelin is not really usable. ``` ldapRealm = org.apache.zeppelin.realm.LdapGroupRealm ## search base for ldap groups (only relevant for LdapGroupRealm): ldapRealm.contextFactory.environment[ldap.searchBase] = dc=ddw,dc=local ldapRealm.contextFactory.url = ldap://lldap:3890 ldapRealm.userDnTemplate = uid={0},ou=people,dc=ddw,dc=local ldapRealm.contextFactory.authenticationMechanism = simple ldapRealm.contextFactory.systemUsername = uid=guest,ou=people,dc=ddw,dc=local ldapRealm.contextFactory.systemPassword = guest-password ``` When changing to the advanced configuration, no login is possible. ``` ldapRealm=org.apache.zeppelin.realm.LdapRealm ldapRealm.contextFactory.authenticationMechanism = simple ldapRealm.contextFactory.url = ldap://lldap:3890 ldapRealm.userDnTemplate = uid={0},ou=people,dc=ddw,dc=local # Ability to set ldap paging Size if needed default is 100 ldapRealm.pagingSize = 200 ldapRealm.authorizationEnabled = true ldapRealm.searchBase = dc=ddw,dc=local ldapRealm.userSearchBase = dc=ddw,dc=local ldapRealm.groupSearchBase = ou=groups,dc=ddw,dc=local ldapRealm.groupObjectClass = groupOfUniqueNames # Allow userSearchAttribute to be customized # If userSearchAttributeName was configured, Zeppelin would use userObjectClass and userSearchAttributeName to search for an actual user DN # Otherwise, memberAttributeValueTemplate would be used to construct the user DN. ldapRealm.userSearchAttributeName = uid ldapRealm.memberAttribute = memberOf # force usernames returned from ldap to lowercase useful for AD ldapRealm.userLowerCase = false # ability set searchScopes subtree (default), one, base ldapRealm.userSearchScope = subtree; ldapRealm.groupSearchScope = subtree; ldapRealm.memberAttributeValueTemplate = cn={0},ou=people,dc=ddw,dc=local ldapRealm.contextFactory.systemUsername = uid=guest,ou=people,dc=ddw,dc=local ldapRealm.contextFactory.systemPassword = guest-password # enable support for nested groups using the LDAP_MATCHING_RULE_IN_CHAIN operator ldapRealm.groupSearchEnableMatchingRuleInChain = true # optional mapping from physical groups to logical application roles ldapRealm.rolesByGroup = ddw: admin_role, LDN_USERS: user_role, NYK_USERS: user_role, HKG_USERS: user_role, GLOBAL_ADMIN: admin_role # optional list of roles that are allowed to authenticate. Incase not present all groups are allowed to authenticate (login). # This changes nothing for url specific permissions that will continue to work as specified in [urls]. ldapRealm.allowedRolesForAuthentication = admin_role,user_role ldapRealm.permissionsByRole = user_role: "*:ToDoItemsJdo:*:*, *:ToDoItem:*:*", admin_role: "*" securityManager.sessionManager = $sessionManager securityManager.realms = $ldapRealm ``` When logging in, zeppelin complains about: ``` zeppelin-1 | WARN [2025-03-07 18:51:43,898] ({qtp96406857-24} AbstractAuthenticator.java[authenticate]:216) - Authentication failed for token submission [org.apache.shiro.authc.UsernamePasswordToken - null, rememberMe=false (10.10.10.1)]. Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException). zeppelin-1 | org.apache.shiro.ldap.UnsupportedAuthenticationMechanismException: Unsupported configured authentication mechanism zeppelin-1 | Caused by: javax.naming.AuthenticationNotSupportedException: [LDAP: error code 48 - Anonymous bind not allowed] ``` it seems the guest-user cannot authenticate. https://zeppelin.apache.org/docs/latest/setup/security/shiro_authentication.html [lldap.log](https://github.com/user-attachments/files/19131987/lldap.log)
Author
Owner

@nitnelave commented on GitHub (Mar 7, 2025):

Here's what I can tell you from these logs:

  • Zeppelin tried to log in as the anonymous user, that was denied. I don't know why it tried that
  • Then it tried to log in as "guest", which succeeded. Guest is an unprivileged user (not a member of lldap_admin, lldap_password_manager or lldap_strict_readonly)
  • As guest, it requested the group "test". Given that "guest" is not a privileged user, it can only see the groups that it's a member of. It was not a member of "test" (idk whether the group exists), so nothing was returned.
<!-- gh-comment-id:2707226709 --> @nitnelave commented on GitHub (Mar 7, 2025): Here's what I can tell you from these logs: - Zeppelin tried to log in as the anonymous user, that was denied. I don't know why it tried that - Then it tried to log in as "guest", which succeeded. Guest is an unprivileged user (not a member of lldap_admin, lldap_password_manager or lldap_strict_readonly) - As guest, it requested the group "test". Given that "guest" is not a privileged user, it can only see the groups that it's a member of. It was not a member of "test" (idk whether the group exists), so nothing was returned.
Author
Owner

@DevId-E commented on GitHub (Mar 7, 2025):

Thanks for the fast reply. "test" is actually the User i tried to login with. Maybe the configuration for ldapRealm.memberAttributeValueTemplate is wrong?

<!-- gh-comment-id:2707258695 --> @DevId-E commented on GitHub (Mar 7, 2025): Thanks for the fast reply. "test" is actually the User i tried to login with. Maybe the configuration for ldapRealm.memberAttributeValueTemplate is wrong?
Author
Owner

@nitnelave commented on GitHub (Mar 7, 2025):

Oh, sorry, I misread the logs, it's not trying to find the group, but the user "test".

A few notes:
ldapRealm.userSearchBase could be ou=people,...
The system user (the one you called guest, but it should really be a service user, like zeppelin) should be a member of at least lldap_strict_readonly. Otherwise it won't see other users. That's probably the main problem.

<!-- gh-comment-id:2707281580 --> @nitnelave commented on GitHub (Mar 7, 2025): Oh, sorry, I misread the logs, it's not trying to find the group, but the user "test". A few notes: ldapRealm.userSearchBase could be `ou=people,...` The system user (the one you called guest, but it should really be a service user, like zeppelin) should be a member of at least lldap_strict_readonly. Otherwise it won't see other users. That's probably the main problem.
Author
Owner

@DevId-E commented on GitHub (Mar 8, 2025):

Thank you for your help!

Adding the guest user (as a temporary service user while setting things up) to the lldap_strict_readonly group changed the behaviour of zeppelin. Now zeppelin throws

zeppelin-1  |  WARN [2025-03-08 07:15:22,803] ({qtp96406857-23} LdapRealm.java[getRoles]:324) - Failed to get roles in current context for test
zeppelin-1  | javax.naming.OperationNotSupportedException: [LDAP: error code 53 - Unsupported group filter: Extensible(LdapMatchingRuleAssertion { matching_rule: Some("1.2.840.113556.1.4.1941"), type_: Some("memberOf"), match_value: "uid=test,ou=people,dc=ddw,dc=local", dn_attributes: false })]; remaining name 'ou=groups,dc=ddw,dc=local'
zeppelin-1  |  WARN [2025-03-08 07:15:22,819] ({qtp96406857-23} LdapRealm.java[doGetAuthenticationInfo]:212) - Encountered Error while authenticating test: LDAP naming error while attempting to authenticate user.
zeppelin-1  | ERROR [2025-03-08 07:15:22,822] ({qtp96406857-23} LoginRestApi.java[proceedToLogin]:209) - Exception in login: 
zeppelin-1  | org.apache.shiro.authc.AuthenticationException: LDAP naming error while attempting to authenticate user.

lldap.log

<!-- gh-comment-id:2708095530 --> @DevId-E commented on GitHub (Mar 8, 2025): Thank you for your help! Adding the guest user (as a temporary service user while setting things up) to the lldap_strict_readonly group changed the behaviour of zeppelin. Now zeppelin throws ``` zeppelin-1 | WARN [2025-03-08 07:15:22,803] ({qtp96406857-23} LdapRealm.java[getRoles]:324) - Failed to get roles in current context for test zeppelin-1 | javax.naming.OperationNotSupportedException: [LDAP: error code 53 - Unsupported group filter: Extensible(LdapMatchingRuleAssertion { matching_rule: Some("1.2.840.113556.1.4.1941"), type_: Some("memberOf"), match_value: "uid=test,ou=people,dc=ddw,dc=local", dn_attributes: false })]; remaining name 'ou=groups,dc=ddw,dc=local' zeppelin-1 | WARN [2025-03-08 07:15:22,819] ({qtp96406857-23} LdapRealm.java[doGetAuthenticationInfo]:212) - Encountered Error while authenticating test: LDAP naming error while attempting to authenticate user. zeppelin-1 | ERROR [2025-03-08 07:15:22,822] ({qtp96406857-23} LoginRestApi.java[proceedToLogin]:209) - Exception in login: zeppelin-1 | org.apache.shiro.authc.AuthenticationException: LDAP naming error while attempting to authenticate user. ``` [lldap.log](https://github.com/user-attachments/files/19142234/lldap.log)
Author
Owner

@nitnelave commented on GitHub (Mar 8, 2025):

I see. Zeppelin is requesting "nested" group membership, which we don't support. If there's no way to disable that on zeppelin side, you'll need support in LLDAP. We have an issue for that, but it's quite a bit of work (and I don't have time for this now)

<!-- gh-comment-id:2708099940 --> @nitnelave commented on GitHub (Mar 8, 2025): I see. Zeppelin is requesting "nested" group membership, which we don't support. If there's no way to disable that on zeppelin side, you'll need support in LLDAP. We have an issue for that, but it's quite a bit of work (and I don't have time for this now)
Author
Owner

@DevId-E commented on GitHub (Mar 8, 2025):

There is a switch for nested groups. When disabling we're back at 48-anonymous bind not allowed. Do you have an idea why this is happening?

I still wonder why log in with LdapGroupRealm is working even without lldap_strict_read on guest user but role/groups are not mapped.

https://github.com/apache/zeppelin/blob/master/zeppelin-server/src/main/java/org/apache/zeppelin/realm/LdapGroupRealm.java

String searchFilter = "(&(objectClass=groupOfNames)(member=" + userDnTemplate + "))"; is hard coded in LdapGroupRealms. Any way of making that work with lldap?

<!-- gh-comment-id:2708105146 --> @DevId-E commented on GitHub (Mar 8, 2025): There is a switch for nested groups. When disabling we're back at 48-anonymous bind not allowed. Do you have an idea why this is happening? I still wonder why log in with LdapGroupRealm is working even without lldap_strict_read on guest user but role/groups are not mapped. https://github.com/apache/zeppelin/blob/master/zeppelin-server/src/main/java/org/apache/zeppelin/realm/LdapGroupRealm.java `String searchFilter = "(&(objectClass=groupOfNames)(member=" + userDnTemplate + "))";` is hard coded in LdapGroupRealms. Any way of making that work with lldap?
Author
Owner

@nitnelave commented on GitHub (Mar 8, 2025):

I can't know exactly what zeppelin does with the LLDAP logs, but I guess it tries to log in as test directly, instead of using a service user to check the group. That's another, simpler way of working with LDAP.

Are you sure the anonymous bind is an issue? It looked like it was retrying after that

<!-- gh-comment-id:2708186748 --> @nitnelave commented on GitHub (Mar 8, 2025): I can't know exactly what zeppelin does with the LLDAP logs, but I guess it tries to log in as test directly, instead of using a service user to check the group. That's another, simpler way of working with LDAP. Are you sure the anonymous bind is an issue? It looked like it was retrying after that
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/lldap-lldap#400
No description provided.