Skip to content

Instantly share code, notes, and snippets.

@acatejr
Created November 18, 2014 22:54
Show Gist options
  • Save acatejr/7af040add1361bfb4464 to your computer and use it in GitHub Desktop.
Save acatejr/7af040add1361bfb4464 to your computer and use it in GitHub Desktop.
Active Directory authentication for Django
from django.contrib.auth.models import User
import ldap
import logging
class ActiveDirectoryBackend:
def __init__(self):
# LDAP server
self.ldap_server = "[server name here]"
# Base directory name
self.base_dn = '[base dn here]'
# Set user attributes returned from ldap queries
# ['memberOf', 'userPrincipalName']
self.attrs = ['displayName', 'company', 'mail', 'userPrincipalName']
self.who = "[user name here]"
self.creds = "[password here]"
# Get an instance of a logger
self.logger = logging.getLogger(__name__)
def get_ldap_user(self, user_id):
"""
Finding a user results in a list of user attributes.
If user is not found in ldap then resulting list is empty.
"""
l = ldap.initialize(self.ldap_server)
l.simple_bind_s(self.who, self.creds)
l.protocol_version = ldap.VERSION3
l.set_option(ldap.OPT_REFERRALS, 0)
l.set_option(ldap.OPT_SIZELIMIT, 5)
criteria = "(&(objectClass=user)(samaccountname=%s))" % user_id
results = l.search_s(self.base_dn, ldap.SCOPE_SUBTREE, criteria, self.attrs)
# Build a usable dictionary of the results
results = [entry for dn, entry in results if isinstance(entry, dict)]
return results
def authenticate(self, username=None, password=None):
user = None
ldap_user = self.get_ldap_user(username)
if not ldap_user:
return None
else:
# User is in ldap. Is user in app db
user = User.objects.filter(username=username)
if not user:
if ldap_user[0]['userPrincipalName'][0]:
email = ldap_user[0]['userPrincipalName'][0].strip()
else:
email = ''
user = User(username=username, email=email)
user.save()
else:
user = User.objects.get(username=username)
try:
if self.check_password(username, password):
return user
else:
return None
except User.DoesNotExist:
return None
def get_user(self, user_id):
ldap_user = self.get_ldap_user(user_id)
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
def check_password(self, username, password):
result = False
ldap_client = None
try:
# build a client
ldap_client = ldap.initialize(self.ldap_server)
# perform a synchronous bind
ldap_client.set_option(ldap.OPT_REFERRALS,0)
user = "%s@[host name here]" % username
ldap_client.simple_bind_s(user, password)
ldap_client.unbind()
result = True
except ldap.INVALID_CREDENTIALS:
self.logger.error('Wrong username and/or password.')
ldap_client.unbind()
result = False
except ldap.SERVER_DOWN:
self.logger.se('ActiveDirectory server not available.')
ldap_client.unbind()
result = False
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment