我正在使用django_auth_ldap - 我们有一个现有的用户数据库,以及一个与我已有的用户数据库共享用户名的外部LDAP系统。
我真的可以做一个如何
的简单例子任何人都可以提供(希望)几行代码,以获得如何执行此操作的简单示例吗?
谢谢!
答案 0 :(得分:1)
在你的python设置文件中添加行
AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.ActiveDirectoryGroupMembershipSSLBackend',
'django.contrib.auth.backends.ModelBackend'
)
以下是我的代码,只需将其替换为您的信息即可。将此文件另存为backend.py将文件放入名为django_auth_ldap的文件夹中。确保文件夹中包含__init.py。
import ldap;
from django.contrib.auth.models import User, Group
class ActiveDirectoryGroupMembershipSSLBackend:
#Required parameters
AD_DNS_NAME ='your remote ldap server location';
AD_LDAP_PORT = 636
AD_LDAP_URL = 'ldaps://%s' % AD_DNS_NAME;
AD_SEARCH_DN = 'dc=bbc,dc=ad,dc=bcc,dc=net'; # this is your search dn
AD_NT4_DOMAIN = 'bbc.ad.bbc.net'; #its your ad domain
AD_SEARCH_FIELDS = ['mail','givenName','sn','sAMAccountName','memberOf'];
AD_MEMBERSHIP_REQ = ['Group_Required','Alternative_Group'];
AD_CERT_FILE = "C:/player/Python/Application/cert/mycert.cer";
AD_DEBUG = False;
AD_DEBUG_FILE ='';
def authenticate(self,username=None,password=None):
try:
if len(password) == 0:
return None
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, 2)
l = ldap.initialize(self.AD_LDAP_URL)
l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
binddn = "%s@%s" % (username,self.AD_NT4_DOMAIN)
l.simple_bind_s(binddn,password)
l.unbind_s()
return self.get_or_create_user(username,password)
except ImportError:
pass
except ldap.INVALID_CREDENTIALS:
pass
def get_or_create_user(self, username, password):
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
try:
# debug info
debug=0
if len(self.AD_DEBUG_FILE) > 0:
if self.AD_DEBUG:
debug = open(self.AD_DEBUG_FILE,'w')
print >>debug, "create user %s" % username
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,self.AD_CERT_FILE)
ldap.set_option(ldap.OPT_REFERRALS,0) # DO NOT TURN THIS OFF OR SEARCH WON'T WORK!
# initialize
if debug:
print >>debug, 'ldap.initialize...'
l = ldap.initialize(self.AD_LDAP_URL)
l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
# bind
if debug:
print >>debug, 'bind...'
binddn = "%s@%s" % (username,self.AD_NT4_DOMAIN)
l.bind_s(binddn,password)
# search
if debug:
print >>debug, 'search...'
result = l.search_ext_s(self.AD_SEARCH_DN,ldap.SCOPE_SUBTREE,"sAMAccountName=%s" % username,self.AD_SEARCH_FIELDS)[0][1]
if debug:
print >>debug, result
# Validate that they are a member of review board group
if result.has_key('memberOf'):
membership = result['memberOf']
else:
membership = None
if debug:
print >>debug, "required:%s" % self.AD_MEMBERSHIP_REQ
bValid=0
for req_group in self.AD_MEMBERSHIP_REQ:
if debug:
print >>debug, "Check for %s group..." % req_group
for group in membership:
group_str="CN=%s," % req_group
if group.find(group_str) >= 0:
if debug:
print >>debug, "User authorized: group_str membership found!"
bValid=1
break
if bValid == 0:
if debug:
print >>debug, "User not authorized, correct group membership not found!"
return None
# get email
if result.has_key('mail'):
mail = result['mail'][0]
else:
mail = None
if debug:
print >>debug, "mail=%s" % mail
# get surname
if result.has_key('sn'):
last_name = result['sn'][0]
else:
last_name = None
if debug:
print >>debug, "sn=%s" % last_name
# get display name
if result.has_key('givenName'):
first_name = result['givenName'][0]
else:
first_name = None
if debug:
print >>debug, "first_name=%s" % first_name
l.unbind_s()
user = User(username=username,first_name=first_name,last_name=last_name,email=mail)
except Exception, e:
if debug:
print >>debug, "exception caught!"
print >>debug, e
return None
user.is_staff = False
user.is_superuser = False
user.set_password('ldap authenticated')
user.save()
# add user to default group
group=Group.objects.get(pk=1)
if debug:
print >>debug, group
if debug:
print >>debug, "add %s to group %s" % (username,group)
user.groups.add(group)
user.save()
if debug:
print >>debug, "successful group add"
if debug:
debug.close()
return user
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
答案 1 :(得分:0)
您是否正在尝试为您的MS Windows用户提供一些单点登录解决方案?
然后,您将在http://docs.djangoproject.com/en/dev/howto/auth-remote-user/
中找到所需的所有提示答案 2 :(得分:-1)
首先,我建议要求用户提供sAMAccountName(这是确切的Windows登录名,通常' firstName.lastName',对于用户名称中有多个单词也更好)而不是仅使用cn用户名(' firstName lastName')。
以下是我完整的LDAPUserAuthBackend代码,并将其添加到 AUTHENTICATION_BACKENDS
from django.contrib.auth.backends import RemoteUserBackend
from django.contrib.auth.models import User, Permission
from django.conf import settings
import ldap
import re
import logging
log = logging.getLogger(__name__)
INTERNAL_USER = None
class LDAPUserAuthBackend(RemoteUserBackend):
create_unknown_user = False
def authenticate(self, username=None, password=None, **kwargs):
# if username or password is not given, then skip
if not username or not password:
return None
try:
# initialize connection to ActiveDirectory the property contains ldap url like ldap://hostname:389
connect = ldap.initialize(settings.AUTH_LDAP_SERVER_URL)
# if user just provide account name portion 'fistName.lastName' on username
# then use your company default domain
if '\\' not in username:
connect.simple_bind_s(username + '@myCompanyDomain.com', password)
base_dn = 'cn=users,dc=myCompanyDomain,dc=com'
search_filter = '(&(objectClass=user)(sAMAccountName=' + username + '))'
else:
# if user provides domain info in username like 'myCompanyDomain\firstName.lastName'
domain, account_name = username.split('\\')
connect.simple_bind_s('{user_name}@{domain_name}.com'.format(user_name=account_name, domain_name=domain), password)
base_dn = 'cn=users,dc={domain_name},dc=com,'.format(domain_name=domain)
search_filter = '(&(objectClass=user)(sAMAccountName=' + account_name + '))'
username = account_name
result = connect.search_s(base_dn, ldap.SCOPE_SUBTREE, search_filter, ['memberOf'])
log.debug(result)
# if search result is found, result will be [(user_dn,{'memberOf':['group cn'...]}]
if result:
result_user_dn, result_dict = result[0]
groups = ','.join(result_dict.get('memberOf')).lower()
# check member is belong to the group
if result_user_dn:
if settings.STAFF_USER_GROUP.lower() in groups or \
settings.ADMIN_USER_GROUP.lower() in groups:
user, created = User.objects.get_or_create(username=username)
first_name, last_name = re.split('\.', username)
user.first_name = first_name
user.last_name = last_name
user.is_active = True
user.is_staff = True
if settings.ADMIN_USER_GROUP.lower() in groups:
user.is_superuser = True
global INTERNAL_USER
INTERNAL_USER = user
return user
log.info('fail to authorize user, username: {}'.format(username))
return None
except ldap.LDAPError as e:
log.warning('authentication error, detail: {}'.format(str(e)))
return None
finally:
connect.unbind_s()
def get_user(self, user_id):
# don't want to go back to database.
# once auth via LDAP successful, that is the user
# because of the user_id is for user passed auth via this backend
global INTERNAL_USER
return INTERNAL_USER