Ldap authentication using django_auth_ldap

295 views
Skip to first unread message

RDN

unread,
Sep 25, 2014, 3:03:28 AM9/25/14
to django...@googlegroups.com
This is my settings.py file. I am trying to create an application where the user will be able to login using their windows credentials. 




import os
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

SECRET_KEY = '_7)uzbsm4*u*ncc6@u(ej9wmy_5+#ol^wdhqh3kf$honrwslh='

DEBUG = True

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = []



# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'sep24'
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

#########################################################
AUTH_LDAP_GLOBAL_OPTIONS ={
    ldap.OPT_X_TLS_REQUIRE_CERT:False,
    ldap.OPT_REFERRALS:False,
}
# Baseline configuration.
AUTH_LDAP_SERVER_URI = "ldap://com.example..../"
AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=....,dc=.....,dc=.....,dc=......"
AUTH_LDAP_BIND_DN = "CN=r...@com.example,DC=.....,DC=.....,DC=....."
AUTH_LDAP_BIND_PASSWORD = "password..."
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=Groups,ou=......,dc=........,dc=.........,dc=.......",
    ldap.SCOPE_SUBTREE, "(uid=%(User)s)")
# or perhaps:
# AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com"

# Set up the basic group parameters.
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou= Groups,ou=...,dc=........,dc=...........,dc=...........",
    ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
)
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr="cn")

# Simple group restrictions
AUTH_LDAP_REQUIRE_GROUP = "cn=enabled,ou=Groups,ou=......,dc=.........,dc=..........,dc=........"
AUTH_LDAP_DENY_GROUP = "cn=disabled,ou=.Groups,ou=...........,dc=.......,dc=..........,dc=......."

# 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 = {
    "Domain Users": "cn=Users,ou=Groups,ou=.........,dc=.........,dc=.........,dc=...........",
    "SCS-Employees-Pune": "cn=Users,ou= Groups,ou=...........,dc=..........,dc=..........,dc=......",
    "SCSPuneEmployees": "cn=superuser,ou=Groups,ou=.......,dc=.........,dc=.........,dc=............."
}

#AUTH_LDAP_PROFILE_FLAGS_BY_GROUP = {
 #   "is_awesome": "cn=Users,ou=Groups,ou=........,dc=..........,dc=.............,dc=.........",
#}

# 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 = 3600
AUTH_LDAP_MIRROR_GROUPS = True
AUTH_LDAP_AUTHORIZE_ALL_USERS = True

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

ROOT_URLCONF = 'sep24.urls'

WSGI_APPLICATION = 'sep24.wsgi.application'


# Database

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Internationalization

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)

STATIC_URL = '/static/'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler'
        },
        'stream_to_console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler'
        },
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        'django_auth_ldap': {
            'handlers': ['stream_to_console'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}
import logging

logger = logging.getLogger('django_auth_ldap')
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)



Now the app is running properly without any error. But I am not able to login into the admin page using my windows credentials. What is wrong.

Lachlan Musicman

unread,
Sep 25, 2014, 7:53:46 AM9/25/14
to django...@googlegroups.com
When you say "running properly" do you mean "we can log in to the
regular site, but not the admin site"? Or do you mean "runserver
starts without error"?

Cheers
L.
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users...@googlegroups.com.
> To post to this group, send email to django...@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/b8c7b703-ba24-4654-8515-6a0beee1282a%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
You have to be really clever to come up with a genuinely dangerous
thought. I am disheartened that people can be clever enough to do that
and not clever enough to do the obvious thing and KEEP THEIR IDIOT
MOUTHS SHUT about it, because it is much more important to sound
intelligent when talking to your friends.
This post was STUPID.
-----------------------------------------------------------------------------------------------------------
The Most Terrifying Thought Experiment of All Time
http://www.slate.com/articles/technology/bitwise/2014/07/roko_s_basilisk_the_most_terrifying_thought_experiment_of_all_time.html

Mario Gudelj

unread,
Sep 25, 2014, 8:56:49 AM9/25/14
to django...@googlegroups.com

If that's the actual file it certainly won't work. You don't even have ldap server address setup. And those dots in dn, what is that?

--

Mario Gudelj

unread,
Sep 25, 2014, 9:19:21 AM9/25/14
to django...@googlegroups.com
I've sent the last email prematurely. I'm sorry about that.

The way I normally set this up is I'll use 2 backends:

AUTHENTICATION_BACKENDS = (
        'django_auth_ldap.backend.LDAPBackend',
        'django.contrib.auth.backends.ModelBackend',
    )

If the LDAP backend fails the Django will try the standard ModelBackend, so this way you can have non LDAP users on the system.

But then in your LDAP settings you'll have the following:

AUTH_LDAP_SERVER_URI = "ldaps://192.168.20.20:636"

That IP will be different in your case but you have to tell Django where it's going to connect to.

It depends on the server setup, but sometimes you'll have to bind before performing a search and sometimes you won't. If you do, and this is something you can find out from the person who's setup the LDAP server, you'll need to supply AUTH_LDAP_BIND_DN and AUTH_LDAP_BIND_PASSWORD. Note that AUTH_LDAP_BIND_DN is usually in this format "base_dn\user".

Now do this part:

AUTH_LDAP_USER_SEARCH = LDAPSearchUnion(
    LDAPSearch("dc=dn_higher,dc= dn_low", ldap.SCOPE_SUBTREE, "(sAMAccountName=%(user)s)"),
)

sAMAccountName part is not always the same. But if you have just a base DN you can figure out the rest from the response. Here's something you can run in the shell that can help:

import ldap
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
l = ldap.initialize("ldaps://192.168.20.20:636")
l.set_option(ldap.OPT_REFERRALS, 0)
l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
l.set_option(ldap.OPT_X_TLS,ldap.OPT_X_TLS_DEMAND)
l.set_option( ldap.OPT_X_TLS_DEMAND, True )
l.set_option( ldap.OPT_DEBUG_LEVEL, 255 )
searchScope = ldap.SCOPE_SUBTREE
retrieveAttributes = None
l.bind("base_dn\user", "password")
baseDN = "dc=domain,dc=local"
searchFilter = "cn=*username_here*"
ldap_result_id = l.search(baseDN, searchScope, searchFilter)
result_set = []
while 1:
    result_type, result_data = l.result(ldap_result_id, 0)
    if (result_data == []):
        break
    else:
        if result_type == ldap.RES_SEARCH_ENTRY:
            result_set.append(result_data)
    print result_set

Oh, and the backend uses the old User from django.contrib.auth.models so you may need to do some changes to the django_auth_ldap code if you have extended AbstractUser or if you're using email for authentication.

Good luck! I hope you don't spend too much time setting this up and I hope this helps.
Reply all
Reply to author
Forward
0 new messages