Configuring an LDAP authentication provider
Configuring an LDAP provider
To configure an LDAP provider, you need to create a configuration for connection to an LDAP server and user attribute mapping.
Main configuration parameters
{
slug: 'openldap', // Unique provider ID
title: 'OpenLDAP', // Displayed provider name
type: 'ldap', // Provider type (use 'ldap')
defaultRole: 'datalens.visitor', // Default role for new users
config: {
// LDAP server connection parameters
url: 'ldap://localhost:8389', // LDAP server URL
bindDN: 'cn=admin,dc=example,dc=org', // DN for the administrative connection
bindCredentials: 'admin', // Administrative connection password
bindProperty: 'dn', // Administrative connection attribute
// User search parameters
searchBase: 'ou=users,dc=example,dc=org', // User search base
searchFilter: '(uid={{username}})', // User search filter
searchScope: 'sub', // Search area: 'base', 'one', or 'sub'
// Group search parameters (optional)
groupSearchBase: 'ou=groups,dc=example,dc=org', // Group search base
groupSearchFilter: '(&(objectClass=groupOfNames)(member={{dn}}))', // Group search filter
groupDnProperty: 'dn', // Group DN attribute
groupSearchScope: 'sub', // Group search area
// User attribute mapping (optional)
userAttributes: {
userId: 'uid', // User ID attribute ('uid' by default)
login: 'uid', // User login attribute ('uid' by default)
email: 'mail', // User email address attribute ('mail' by default)
firstName: 'givenName', // User first name attribute ('givenName' by default)
lastName: 'sn', // User last name attribute ('sn' by default)
},
// Group attribute mapping (optional)
groupAttributes: {
groupId: 'dn', // Group ID attribute ('dn' by default)
title: 'cn', // Group name attribute ('cn' by default)
},
// Mapping of DataLens roles for LDAP groups (optional)
roleToGroupId: {
'datalens.admin': 'cn=datalensadmin,ou=groups,dc=example,dc=org',
'datalens.creator': 'cn=datalenscreator,ou=groups,dc=example,dc=org',
'datalens.visitor': 'cn=datalensvisitor,ou=groups,dc=example,dc=org',
},
// Additional settings
syncUserRoles: true, // Synchronizing user roles at each log-in (true by default)
syncUserGroups: true, // Synchronizing user groups at each log-in (true by default)
}
}
Detailed description of parameters
Basic parameters
- slug: Unique provider ID used in URLs and internal IDs.
- title: Provider name displayed in the interface.
- type: Provider type; for LDAP, use
ldap. - defaultRole: Role assigned to the user if unable to define a role according to LDAP groups.
LDAP server connection parameters
- url: LDAP server URL, e.g.,
ldap://localhost:389orldaps://ldap.example.com:636. - bindDN: Unique Distinguished Name (DN) for the administrative LDAP server connection.
- bindCredentials: Administrative connection password.
- bindProperty: User’s LDAP object attribute used for password checking as a bind property, e.g.,
name,email. The default value isdn.
User search parameters
-
searchBase: User search base in LDAP, e.g.,
ou=users,dc=example,dc=org. -
searchFilter: User search filter. Use the
{{username}}template to substitute the login entered by the user. -
searchScope: Search area:
base: Search in the specified base only.one: Search in the base and one level below.sub: Recursive search in all subtrees.
Group search parameters (optional)
- groupSearchBase: Group search base in LDAP, e.g.,
ou=groups,dc=example,dc=org. - groupSearchFilter: Group search filter. Use
{{dn}}to substitute the DN of the found user. - groupDnProperty: User object attribute used to interpolate
{{dn}}for groupSearchFilter (dnby default). - groupSearchScope: Group search area (similar to searchScope).
// User attribute mapping
Allows you to set up the mapping between the LDAP user attributes and the user’s fields in the system:
- userId: User ID attribute (
uidby default). - login: User login attribute (
uidby default). - email: User email address attribute (
mailby default). - firstName: User first name attribute (
givenNameby default). - lastName: User last name attribute (
snby default).
Group attribute mapping
Allows you to set up the mapping between the LDAP groups' attributes and the groups' fields in the system:
- groupId: Group ID attribute (
dnby default). - title: Group name attribute (
cnby default).
Mapping of LDAP group roles
Allows you to set up the mapping between DataLens roles and LDAP groups.
Algorithm of synchronization between groups and roles:
- A search for the user's LDAP groups is performed.
- For each group, a search is performed in
roleToGroupIdbased on the group ID (an attribute fromgroupAttributes). Once a group is found inroleToGroupId, a relevant role will be assigned to the user.
For example:
roleToGroupId: {
'datalens.admin': 'cn=datalensadmin,ou=groups,dc=example,dc=org',
'datalens.creator': 'cn=datalenscreator,ou=groups,dc=example,dc=org',
'datalens.visitor': 'cn=datalensvisitor,ou=groups,dc=example,dc=org',
}
Where:
'cn=datalensadmin,ou=groups,dc=example,dc=org','cn=datalenscreator,ou=groups,dc=example,dc=org', and'cn=datalensvisitor,ou=groups,dc=example,dc=org': Group IDs and the search base (ou=groups,dc=example,dc=org) in LDAP.'datalens.admin','datalens.creator', and'datalens.visitor': DataLens roles.
If the user is a member of the cn=datalensadmin group, the datalens.admin role will be assigned.
Additional settings
- syncUserRoles: When set to
true(default value), user roles will be synchronized at each log-in. - syncUserGroups: When set to
true(default value), user groups will be synchronized at each log-in.
Aspects of role and group synchronization
User roles and groups are synchronized the moment the user logs in to the system. If the user is a member of a group specified in the configuration, the relevant role will be assigned to the user, and the group will appear in DataLens and will be available in the access permissions. If the user is not a group member, the default role will be assigned. If there are more than 100 groups, synchronization will be skipped. If you need to synchronize more groups, set up regular group synchronization using a synchronization script.
Example of an OpenLDAP configuration
const ldapConfig = {
slug: 'openldap',
title: 'OpenLDAP',
type: 'ldap',
defaultRole: 'datalens.visitor',
config: {
url: 'ldap://ldap.example.com:389',
bindDN: 'cn=admin,dc=example,dc=org',
bindCredentials: 'admin_password',
searchBase: 'ou=users,dc=example,dc=org',
searchFilter: '(uid={{username}})',
groupSearchBase: 'ou=groups,dc=example,dc=org',
groupSearchFilter: '(&(objectClass=groupOfNames)(member={{dn}}))',
groupDnProperty: 'dn',
searchScope: 'sub',
groupSearchScope: 'sub',
userAttributes: {
userId: 'uid',
login: 'uid',
email: 'mail',
firstName: 'givenName',
lastName: 'sn',
},
groupAttributes: {
groupId: 'dn',
title: 'cn',
},
roleToGroupId: {
'datalens.admin': 'cn=datalensadmin,ou=groups,dc=example,dc=org',
'datalens.creator': 'cn=datalenscreator,ou=groups,dc=example,dc=org',
},
syncUserRoles: true,
syncUserGroups: true,
},
};
Example of an ldif file for an OpenLDAP configuration
## base
dn: ou=users,dc=example,dc=org
changetype: add
ou: users
objectClass: organizationalUnit
description: Org group for users.
dn: ou=groups,dc=example,dc=org
changetype: add
ou: groups
objectClass: organizationalUnit
description: Org group for groups.
## users
dn: uid=bob,ou=users,dc=example,dc=org
changetype: add
uid: bob
cn: Bob Smith
givenName: Bob
sn: Smith
objectClass: inetOrgPerson
userPassword: bob
mail: bob@example.org
dn: uid=al,ou=users,dc=example,dc=org
changetype: add
uid: al
cn: Al Brown
givenName: Al
sn: Brown
objectClass: inetOrgPerson
userPassword: al
mail: al@example.org
dn: uid=carl,ou=users,dc=example,dc=org
changetype: add
uid: carl
cn: Carl Snow
givenName: Carl
sn: Snow
objectClass: inetOrgPerson
userPassword: carl
mail: carl@example.org
## groups
dn: cn=someusers,ou=groups,dc=example,dc=org
changetype: add
objectclass: groupofnames
cn: someusers
description: Some Group
member: uid=al,ou=users,dc=example,dc=org
member: uid=bob,ou=users,dc=example,dc=org
## groups-roles
dn: cn=datalensadmin,ou=groups,dc=example,dc=org
changetype: add
objectclass: groupofnames
cn: datalensadmin
description: Group datalens.admin role
member: uid=bob,ou=users,dc=example,dc=org
dn: cn=datalenscreator,ou=groups,dc=example,dc=org
changetype: add
objectclass: groupofnames
cn: datalenscreator
description: Group datalens.creator role
member: uid=al,ou=users,dc=example,dc=org
ldapsearch
We recommend you to start by testing the configuration with the ldapsearch utility:
# Search for the user
ldapsearch \
-H ldap://ldap.example.com:389 \
-x \
-D cn=admin,dc=example,dc=org \
-w admin \
-b ou=users,dc=example,dc=org \
"(uid=bob)"
# ldapsearch \
# -H ldap://ldap.example.com:389 \ # config.url
# -x \
# -D cn=admin,dc=example,dc=org \ # config.bindDN
# -w admin \ # config.bindCredentials
# -b ou=users,dc=example,dc=org \ # config.searchBase
# "(uid=bob)" # config.searchFilter with {{username}} (user login when logging in to the DL) substituted into the template string
# LDAP response:
# dn: uid=bob,ou=users,dc=example,dc=org
# uid: bob
# cn: Bob Smith
# givenName: Bob
# sn: Smith
# objectClass: inetOrgPerson
# userPassword:: ...
# mail: bob@example.org
# Search for the user's groups
ldapsearch \
-H ldap://ldap.example.com:389 \
-x \
-D cn=admin,dc=example,dc=org \
-w admin \
-b ou=groups,dc=example,dc=org \
"(&(objectClass=groupOfNames)(member=uid=bob,ou=users,dc=example,dc=org))"
# ldapsearch \
# -H ldap://ldap.example.com:389 \ # config.url
# -x \
# -D cn=admin,dc=example,dc=org \ # config.bindDN
# -w admin \ # config.bindCredentials
# -b ou=groups,dc=example,dc=org \ # config.groupSearchBase
# "(&(objectClass=groupOfNames)(member=uid=bob,ou=users,dc=example,dc=org))" # config.groupSearchFilter
# Above, we got the `bob` user and substituted their dn into the template string {{dn}}: (&(objectClass=groupOfNames)(member={{dn}})) according to config.groupDnProperty
# LDAP response:
# someusers, groups, example.org
# dn: cn=someusers,ou=groups,dc=example,dc=org
# objectClass: groupOfNames
# cn: someusers
# description: Some Group
# member: uid=bob,ou=users,dc=example,dc=org
# member: uid=al,ou=users,dc=example,dc=org
# datalensadmin, groups, example.org
# dn: cn=datalensadmin,ou=groups,dc=example,dc=org
# objectClass: groupOfNames
# description: Group datalens.admin role
# member: uid=bob,ou=users,dc=example,dc=org
# cn: datalensadmin
Example of an Active Directory configuration
const adConfig = {
slug: 'active-directory',
title: 'Active Directory',
type: 'ldap',
defaultRole: 'datalens.visitor',
config: {
url: 'ldap://ad.example.com:389',
bindDN: 'CN=Service Account,OU=Service Accounts,DC=example,DC=com',
bindCredentials: 'service_account_password',
searchBase: 'OU=Users,DC=example,DC=com',
searchFilter: '(&(objectClass=user)(sAMAccountName={{username}}))',
groupSearchBase: 'OU=Groups,DC=example,DC=com',
groupSearchFilter: '(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={{dn}}))',
groupDnProperty: 'dn',
searchScope: 'sub',
groupSearchScope: 'sub',
userAttributes: {
userId: 'sAMAccountName',
login: 'sAMAccountName',
email: 'mail',
firstName: 'givenName',
lastName: 'sn',
},
groupAttributes: {
groupId: 'dn',
title: 'cn',
},
roleToGroupId: {
'datalens.admin': 'CN=DatalensAdmins,OU=Groups,DC=example,DC=com',
'datalens.creator': 'CN=DatalensCreators,OU=Groups,DC=example,DC=com',
},
syncUserRoles: true,
syncUserGroups: true,
},
};
Using a configuration
Configuration via the AUTH_PROVIDERS_CONFIG environment variable
To configure authentication providers, the application uses the AUTH_PROVIDERS_CONFIG environment variable. This variable contains a JSON string with an array of configurations of all authentication providers. Currently, only the LDAP provider is supported; however, other provider types will be added in future as well.
Example of the AUTH_PROVIDERS_CONFIG environment variable:
[
{
"slug": "openldap",
"title": "OpenLDAP",
"type": "ldap",
"defaultRole": "datalens.visitor",
"config": {
"url": "ldap://ldap.example.com:389",
"bindDN": "cn=admin,dc=example,dc=org",
"bindCredentials": "admin_password",
"searchBase": "ou=users,dc=example,dc=org",
"searchFilter": "(uid={{username}})",
"groupSearchBase": "ou=groups,dc=example,dc=org",
"groupSearchFilter": "(&(objectClass=groupOfNames)(member={{dn}}))",
"groupDnProperty": "dn",
"searchScope": "sub",
"groupSearchScope": "sub",
"roleToGroupId": {
"datalens.admin": "cn=datalensadmin,ou=groups,dc=example,dc=org",
"datalens.creator": "cn=datalenscreator,ou=groups,dc=example,dc=org"
},
"syncUserRoles": true,
"syncUserGroups": true
}
}
]