LDAP

This page describes configuring Lenses with LDAP.

Lenses can be configured via LDAP handle the user authentication.

The groups that a user belongs to (authorization) may come either from LDAP (automatic mapping) or via manually mapping an LDAP user to a set of Lenses groups.

All the user’s groups are then matched by name (case sensitive) with the groups stored in Lenses. All the matching groups' permissions are combined. If a user has been assigned manually a set of Lenses groups, then the groups coming from LDAP are ignored.

Active Directory (AD) and OpenLDAP (with the memberOf overlay if LDAP group mapping is required) servers are tested and supported in general.

Due to the LDAP standard ambiguity, it is impossible to support all the configurations in the wild. The most common pain point is LDAP group mapping. If the default class that extracts and maps LDAP groups to Lenses groups does not work, it is possible to implement your own.

Before setting up an LDAP connection, we advise you to familiarize yourself with LDAP and/or have access to your LDAP and/or Active Directory administrators.

An LDAP setup example with LDAP group mapping is shown below:

security.conf
# LDAP connection details

lenses.security.ldap.url="ldaps://example.com:636"
## For the LDAP user please use the distinguished name (DN).
## The LDAP user must be able to list users and their groups.
lenses.security.ldap.user="cn=lenses,ou=Services,dc=example,dc=com"
lenses.security.ldap.password="[PASSWORD]"
## When set to true, it uses the lenses.security.ldap.user to read the user's groups
## lenses.security.ldap.use.service.user.search=false

# LDAP user search settings

lenses.security.ldap.base="ou=Users,dc=example,dc=com"
lenses.security.ldap.filter="(&(objectClass=person)(sAMAccountName=<user>))"

# LDAP group search and mapping settings

lenses.security.ldap.plugin.class="io.lenses.security.ldap.LdapMemberOfUserGroupPlugin"
lenses.security.ldap.plugin.group.extract.regex="(?i)CN=(\\w+),ou=Groups.*"
lenses.security.ldap.plugin.memberof.key="memberOf"
lenses.security.ldap.plugin.person.name.key = "sn"

In the example above you can distinguish three key sections for LDAP:

  • the connection settings,

  • the user search settings,

  • and the group search settings.

Lenses uses the connection settings to connect to your LDAP server. The provided account should be able to list users under the base path and their groups. The default group plugin only needs access to the memberOf attributes for each user, but your custom implementation may need different permissions.

When a user tries to log in, a query is sent to the LDAP server for all accounts that are under the lenses.security.ldap.base and match the lenses.security.ldap.filter. The result needs to be unique; a distinguished name (DN) —the user that will log in to Lenses.

In the example, the application would query the LDAP server for all entities under ou=Users,dc=example,dc=com that satisfy the LDAP filter (&(objectClass=person)(sAMAccountName=)) which would be replaced by the username that tries to login to Lenses. A more simple filter could be cn=, which for user Mark would return the DN cn=Mark,ou=Users,dc=example,dc=com.

Once the user has been verified, Lenses queries the user groups and maps them to Lenses groups. For every LDAP group that matches a Lenses group, the user is granted the selected permissions.

Depending on the LDAP setup, only one of the users or the Lenses service user may be able to retrieve the group memberships. This can be controlled by the option lenses.security.ldap.use.service.user.search.

The default value (false) uses the user itself to query for groups. Groups be can be created in the admin section of the web interface, or in the command line via the lenses-cli application.

Set lenses.security.ldap.use.service.user.search to true to use lenses.security.ldap.user account to list a logged user groups when your LDAP setup restricts most of the user's action to list their groups.

Group mapping

When working with LDAP or Active Directory, user and group management is done in LDAP.

Lenses provides fine-grained role-based access (RBAC) for your existing groups of users over data and applications.

Create a group in Lenses with the same name (case-sensitive) as in LDAP/AD.

If mapping LDAP groups to Lenses groups is not desired. Manually map LDAP users to Lenses groups, using the web interface, or the lenses-cli.

LDAP still provides the authentication, but all LDAP groups for this user are ignored.

When you create an LDAP user in Lenses, the username will be used in the search expression set in lenses.security.ldap.filter to authenticate them. If no user should be allowed to use the groups coming from LDAP, then this functionality should be disabled.

Set lenses.security.ldap.plugin.memberof.key or lenses.security.ldap.plugin.group.extract.regex to a bogus entry, rendering it unusable.

An example would be:

lenses.security.ldap.plugin.memberof.key = "notaKey"

Group extract plugin

The group extract plugin is a class that implements an LDAP query that retrieves a user’s groups and makes any necessary transformation to match the LDAP group to a Lenses group name.

The default class implementation that comes with Lenses is io.lenses.security.ldap.LdapMemberOfUserGroupPlugin.

If your LDAP server supports the memberOf functionality, where each user has his/her group memberships added as attributes to his/her entity, you can use it by setting the lenses.security.ldap.plugin.class option to this class:

lenses.security.ldap.plugin.class=io.lenses.security.ldap.LdapMemberOfUserGroupPlugin

Below you will see a brief example of its setup.

security.conf
# Set the full classpath that implements the group extraction
lenses.security.ldap.plugin.class="io.lenses.security.ldap.LdapMemberOfUserGroupPlugin"

# The plugin uses the 'memberOf' attribute. If this attribute has a different
# name in your LDAP set it here.
lenses.security.ldap.plugin.memberof.key="memberOf"

# This regular expression should return the group common name. If it matches
# a Lenses group name, the user is granted its permissions.
# As an example if there is a 'memberOf' attribute with value:
#   cn=LensesAdmins,ou=Groups,dn=example,dn=com
# The regular expression will return 'LensesAdmins'.
# Group names are case sensitive.
lenses.security.ldap.plugin.group.extract.regex="(?i)cn=(\\w+),ou=Groups.*"

# This is the LDAP attribute that holds the user's full name. It's optional.
lenses.security.ldap.plugin.person.name.key = "sn"

As an example, the memberOf search may return two attributes for user Mark:

attribute  value
---------  ------------------------------------------
memberOf   cn=LensesAdmin,ou=Groups,dc=example,dc=com
memberOf   cn=RandomGroup,ou=Groups,dc=example,dc=com

The regular expression (?i)cn=(\w+),ou=Groups.* will return these two regex group matches:

LensesAdmin
RandomGroup

If any of these groups exist in Lenses, Mark will be granted the permissions of the matching groups.

The lenses.security.ldap.plugin.group.extract.regex should contain exactly one regular expression capturing group.

If you need to apply more groups for your matching purposes, you should use non-capturing groups (e.g (?:groupRegex).

As an example, the regular expression (?i)cn=((?:Kafka|Apps)Admin),ou=Groups,dc=example,dc=com applied to memberOf attributes:

attribute  value
---------  ------------------------------------------
memberOf   cn=KafkaAdmin,ou=Groups,dc=example,dc=com
memberOf   cn=AppsAdmin,ou=Groups,dc=example,dc=com
memberOf   cn=BizAdmin,ou=Groups,dc=example,dc=com

will return these two regex group matches:

AppsAdmin
KafkaAdmin

Custom LDAP plugin

If your LDAP does not offer the memberOf functionality or uses a complex setup, you can provide your own implementation. Start with the code on GitHub, create a JAR, and add it to the plugins/ folder and set your implementation’s full classpath:

# Set the full classpath that implements the group extraction
lenses.security.ldap.plugin.class="io.lenses.security.ldap.LdapMemberOfUserGroupPlugin"

Do not forget to grant to the account any permissions it may need for your plugin to work.

LDAP Configuration Options

See configuration settings.

The following configuration entries are specific to the default group plugin. A custom LDAP plugin might require different entries under lenses.security.ldap.plugin:

lenses.security.ldap.plugin.memberof.key
lenses.security.ldap.plugin.person.name.key
lenses.security.ldap.plugin.group.extract.regex
lenses.security.ldap.plugin.person.name.key

Last updated

Logo

2024 © Lenses.io Ltd. Apache, Apache Kafka, Kafka and associated open source project names are trademarks of the Apache Software Foundation.