Enabling LDAP authentication

Cloudera Data Visualization by default uses local account (basic) authentication where users must be created manually through the UI using the default admin user.

This authentication method can be supplemented to also enable LDAP authentication so that corporate credentials can be used to login to ML Data Viz instead.

Prepare your installation by collecting the values of the following LDAP configuration parameters:

Configuration Item Description
AUTH_LDAP_SERVER_URI LDAP server URI for example, "ldap://ldap.example.com".
AUTH_LDAP_BIND_DN Username DN (Distinguished User) of the bind user account. This needs to be the full DN for the Bind User, not just the bind username.
AUTH_LDAP_BIND_PASSWORD Password of the bind user account.
AUTH_LDAP_USER_SEARCH The DN of the subtree that contains users. Often an OU.
AUTH_LDAP_GROUP_SEARCH The DN of the subtree that contains groups. Often an OU.
AUTH_LDAP_REQUIRE_GROUP The DN of a group to which users must belong to have login privileges.
LDAP Group for Admins The DN of the Admins group. Users in this group have admin access.
  1. Click the Gear icon in the upper right corner.
  2. Click on Site Settings.
  3. Locate the section for Advanced Settings. Here you have the following two options:
    OptionDescription
    Option 1: Configuring LDAP authentication with a bind user

    Bind User authentication with LDAP tends to be more flexible with user lookups/searches and also supports Group lookups whereas Direct Bind in Option 2 currently does not. Group lookups allow you to map users in ML Data Viz to Roles automatically so when they login they may have access to Dashboards and Datasets (This requires additional steps in the ML Data Viz Roles setup section).

    However this also requires you to request and maintain a Bind User which may take a little longer to setup at first. You will also occasionally need to update the Bind User password as it will likely expire.

    Here is the code for a simple search/bind approach that completes an anonymous bind, searches the OU for an object that matched the UID of the user’s name, and attempts to bind using that DN and the user’s password. The authentication fails unless the search returns exactly one result. If anonymous search is not possible, set AUTH_LDAP_BIND_DN to the DN of an authorized user, and AUTH_LDAP_BIND_PASSWORD to the password.

    
    import ldap
    from django_auth_ldap.config import LDAPSearch
                                    
    AUTH_LDAP_BIND_DN = ""
    AUTH_LDAP_BIND_PASSWORD = ""
    AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
                                
    Option 2: Direct Bind Approach

    Direct Bind with LDAP explicitly passes the user’s credentials to authenticate with the LDAP server. The advantage of Direct Bind is that doesn’t require you to request and manage a Bind User account. However, the downside to Direct Bind is that Group lookups don’t currently work for logged in users, which means automatic User-Role mapping can’t be configured.

    Here is the code for a simple direct bind approach:

    
    AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = True
    AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com"
                                
  4. If you’re using a Bind User to authenticate you can store the LDAP_DN and LDAP_PASSWORD environment variables in the Project Settings section under the Engine tab for easier management.

Example configuration for Bind User with LDAP_DN and LDAP_PASSWORD project environmental variables in Cloudera Internal EDH:


import ldap
from django_auth_ldap.config import LDAPSearch, NestedActiveDirectoryGroupType, ActiveDirectoryGroupType
                
# Connection options
#AUTH_LDAP_START_TLS = True  # Optional for LDAPS but normally not needed
AUTH_LDAP_SERVER_URI = "ldap://ad-readonly.sjc.cloudera.com:389"
                
# Bind user setup
AUTH_LDAP_BIND_DN = os.getenv('LDAP_DN')
AUTH_LDAP_BIND_PASSWORD = os.getenv('LDAP_PASSWORD')
                
# Required Group for all users to access application
#AUTH_LDAP_REQUIRE_GROUP = "CN=All_Staff_WW,OU=Groups,DC=cloudera,DC=local"
                
# Group for specifying super admins
#AUTH_LDAP_USER_FLAGS_BY_GROUP = {
#  "is_superuser": ["CN=cloud_spend_analysts,OU=Groups,DC=cloudera,DC=local"]
#}
                
# User and group search objects and types
AUTH_LDAP_USER_SEARCH = LDAPSearch("CN=users,DC=cloudera,DC=local", ldap.SCOPE_SUBTREE,"(sAMAccountName=%(user)s)")
                    
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("OU=Groups,DC=cloudera,DC=local", ldap.SCOPE_SUBTREE,"(objectClass=group)")
                
# Map LDAP attributes to Django
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
                
# Cache settings
# Note this may cause a delay when groups are changed in LDAP
AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600*4  # Cache for 4 hours
REMOTE_GROUP_CACHE_TIMEOUT = 3600*4
                
# Group Settings
AUTH_LDAP_GROUP_TYPE = ActiveDirectoryGroupType()
AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_MIRROR_GROUPS = False
                
# Some optional TLS/SSL options when enabling LDAPS
                
#AUTH_LDAP_GLOBAL_OPTIONS = {
#ldap.OPT_X_TLS_CACERTFILE: "/etc/bla.cert",        # Point to CA Cert file
#ldap.OPT_X_TLS_REQUIRE_CERT: ldap.OPT_X_TLS_NEVER, # Disable cert checking
#}
                
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_DEBUG_LEVEL: 1,  # 0 to 255
ldap.OPT_REFERRALS: 0,  # For Active Directory
}
                
# If there is no Bind User you can use these settings, but it's not the preferred way

#AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = True
#AUTH_LDAP_USER_DN_TEMPLATE = "cloudera\%(user)s"
                
# The backend needed to make this work.
AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend,
'django.contrib.auth.backends.ModelBackend'
)                

Example configuration for Direct Bind in Cloudera Internal EDH:


import ldap
from django_auth_ldap.config import LDAPSearch, NestedActiveDirectoryGroupType, ActiveDirectoryGroupType
                
# Connection options
#AUTH_LDAP_START_TLS = True  # Optional for LDAPS but normally not needed
AUTH_LDAP_SERVER_URI = "ldap://ad-readonly.sjc.cloudera.com:389"
                
# Bind user setup
#AUTH_LDAP_BIND_DN = os.getenv('LDAP_DN')
#AUTH_LDAP_BIND_PASSWORD = os.getenv('LDAP_PASSWORD')
                
# Required Group for all users to access application
#AUTH_LDAP_REQUIRE_GROUP = "CN=All_Staff_WW,OU=Groups,DC=cloudera,DC=local"
                
# Group for specifying super admins
#AUTH_LDAP_USER_FLAGS_BY_GROUP = {
#  "is_superuser": ["CN=cloud_spend_analysts,OU=Groups,DC=cloudera,DC=local"]
#}
                
# User and group search objects and types
#AUTH_LDAP_USER_SEARCH = LDAPSearch("CN=users,DC=cloudera,DC=local",
ldap.SCOPE_SUBTREE,"(sAMAccountName=%(user)s)")
                
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("OU=Groups,DC=cloudera,DC=local", ldap.SCOPE_SUBTREE,"(objectClass=group)")
                
# Map LDAP attributes to Django
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
                
# Cache settings
# Note this may cause a delay when groups are changed in LDAP
AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600*4  # Cache for 4 hours
REMOTE_GROUP_CACHE_TIMEOUT = 3600*4
                
# Group Settings
AUTH_LDAP_GROUP_TYPE = ActiveDirectoryGroupType()
AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_MIRROR_GROUPS = False
                
# Some optional TLS/SSL options when enabling LDAPS
                
#AUTH_LDAP_GLOBAL_OPTIONS = {
#ldap.OPT_X_TLS_CACERTFILE: "/etc/bla.cert",        # Point to CA Cert file
#ldap.OPT_X_TLS_REQUIRE_CERT: ldap.OPT_X_TLS_NEVER, # Disable cert checking
#}
                
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_DEBUG_LEVEL: 1,  # 0 to 255
ldap.OPT_REFERRALS: 0,  # For Active Directory
}
                
# If there is no Bind User you can use these settings, but it's not the preferred way
                
AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = True
AUTH_LDAP_USER_DN_TEMPLATE = "cloudera\%(user)s"
                
# The backend needed to make this work.
AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend,
'django.contrib.auth.backends.ModelBackend'
)