Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting groups from LDAP to django

I am using django-ldap-auth to authenticate users against an LDAP-Server (ActiveDirectory). The users are able to login and the flags per user (e.g. is_staff) are set correctly.

I also want to add django-groups to my django-users depending on the ldap-users group. Here're my settings:

import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, ActiveDirectoryGroupType

AUTH_LDAP_SERVER_URI = "ldap://XXX"

AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = True
AUTH_LDAP_BIND_DN = ""
AUTH_LDAP_BIND_PASSWORD = ""

# I somewhere read that this should help, but it didn't:
#AUTH_LDAP_GLOBAL_OPTIONS = {
#    ldap.OPT_REFERRALS: 0
#}

AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=Benutzer,ou=Konten,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX",
ldap.SCOPE_SUBTREE, "(cn=%(user)s)")
AUTH_LDAP_USER_DN_TEMPLATE = "CN=%(user)s,OU=Benutzer,OU=Konten,OU=XXX,OU=XXX,DC=XXX,DC=XXX,DC=XXX"

# Set up the basic group parameters.
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("OU=AnwenderRollen,OU=Gruppen,OU=XXX,OU=XXX,DC=XXX,DC=XXX,DC=XXX",
    ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
)
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr="CN")
# also tried various possibilities for objectClass and AUTH_LDAP_GROUP_TYPE
#AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr="cn")
#AUTH_LDAP_GROUP_TYPE = ActiveDirectoryGroupType(name_attr="cn")


# Populate the Django user from the LDAP directory.
AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenname",
    "last_name": "sn",
    "email": "mail"
}

AUTH_LDAP_PROFILE_ATTR_MAP = {
    #"employee_number": "employeeNumber"
}

AUTH_LDAP_USER_FLAGS_BY_GROUP = {
    #"is_active": "cn=active,ou=django,ou=groups,dc=example,dc=com",
    "is_staff": "CN=GROUPNAME,OU=AnwenderRollen,OU=Gruppen,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX",
    "is_superuser": "CN=GROUPNAME,OU=AnwenderRollen,OU=Gruppen,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX"
}

AUTH_LDAP_PROFILE_FLAGS_BY_GROUP = {
    #"is_awesome": "cn=awesome,ou=django,ou=groups,dc=example,dc=com",
}

# This is the default, but I like to be explicit.
AUTH_LDAP_ALWAYS_UPDATE_USER = True

# Use LDAP group membership to calculate group permissions.
AUTH_LDAP_FIND_GROUP_PERMS = True

# Cache group memberships for an hour to minimize LDAP traffic
AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 1 #3600

# Keep ModelBackend around for per-user permissions and maybe a local
# superuser.
AUTHENTICATION_BACKENDS = (
    'django_auth_ldap.backend.LDAPBackend',
    'django.contrib.auth.backends.ModelBackend',
)

Only parts of this settings work: Login works, a django-user is created, the attributes are taken from LDAP (AUTH_LDAP_USER_ATTR_MAP) and the flags are set (AUTH_LDAP_USER_FLAGS_BY_GROUP) with the same group-path as in AUTH_LDAP_GROUP_SEARCH. But this group search does not work because of this error:

DEBUG Populating Django user USERNAME
DEBUG search_s('CN=USERNAME,OU=Benutzer,OU=Konten,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX', 0, '(objectClass=*)') returned 1 objects: cn=USERNAME,ou=benutzer,ou=konten,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX
DEBUG CN=USERNAME,OU=Benutzer,OU=Konten,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX is a member of cn=GROUPNAME,ou=anwenderrollen,ou=gruppen,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX
DEBUG CN=USERNAME,OU=Benutzer,OU=Konten,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX is a member of cn=GROUPNAME,ou=anwenderrollen,ou=gruppen,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX
DEBUG Django user USERNAMEdoes not have a profile to populate
ERROR search_s('OU=AnwenderRollen,OU=Gruppen,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX', 2, '(&(objectClass=groupOfNames)(member=CN=USERNAME,OU=Benutzer,OU=Konten,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX))') raised OPERATIONS_ERROR({'info': '00000000: LdapErr: DSID-0C090627, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, vece', 'desc': 'Operations error'},)
DEBUG search_s('OU=AnwenderRollen,OU=Gruppen,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX', 2, '(&(objectClass=groupOfNames)(member=CN=USERNAME,OU=Benutzer,ou=XXX,ou=XXX,dc=XXX,dc=XXX,dc=XXX))') returned 0 objects: 

Since the group-paths are the same for the flags and for the group search I was assuming that it should work. Is it a problem to search for groups when binding as authenticating user?

What am I missing?

like image 817
Marius Avatar asked Nov 27 '13 14:11

Marius


People also ask

How does Django connect to LDAP?

You need to configure your LDAP settings in settings.py (as shown in the link you posted) and add your LDAPBackend to AUTHENTICATION_BACKENDS . You can use the default LDAPBackend provided or create a custom one and use that. Check the example linked above for more details.

What is LDAP in Django?

This is a Django authentication backend that authenticates against an LDAP service. Configuration can be as simple as a single distinguished name template, but there are many rich configuration options for working with users, groups, and permissions.

What are Django groups?

What's a group? English Definition: A group is a set of objects which are classed together. Django Definition: Group models are a generic way of categorizing users so you can apply permissions, or some other label, to those users. A user can belong to any number of groups.


1 Answers

Here's what I did to make it work:

AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = True
AUTH_LDAP_BIND_DN = "existing_user"
AUTH_LDAP_BIND_PASSWORD = "existing_password"

and I changed (objectClass=groupOfNames) to (objectClass=top)

It seems that django_auth_ldap uses the bound user to check for the flags (is_staff, ...) but not to check the groups. So I added credentials to these variables which are now used to search for groups.

However, it works!

like image 50
Marius Avatar answered Sep 30 '22 09:09

Marius