Django LDAP电子邮件作为用户名

时间:2018-02-27 08:47:54

标签: python django email authentication ldap

我正在尝试使用电子邮件地址作为LDAP用户登录。我使用了以下代码:

settings.py

AUTH_LDAP_SERVER_URI = "ldap://192.168.12.123"

AUTH_LDAP_BIND_DN = "User"
AUTH_LDAP_BIND_PASSWORD = "Password"
AUTH_LDAP_CONNECTION_OPTIONS = {
    ldap.OPT_DEBUG_LEVEL: 1,
    ldap.OPT_REFERRALS: 0
}

AUTH_LDAP_USER_SEARCH = LDAPSearch("DC=domain,DC=com", ldap.SCOPE_ONELEVEL, "(uid=%(user)s)")
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("DC=domain,DC=com", ldap.SCOPE_SUBTREE, "(objectClass=group)")
AUTH_LDAP_GROUP_TYPE = NestedActiveDirectoryGroupType()

AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail"
}

AUTH_LDAP_ALWAYS_UPDATE_USER = True

LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson"

AUTH_LDAP_FIND_GROUP_PERMS = True

AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600

AUTH_LDAP_E_USER_SEARCH = LDAPSearch("DC=domain,DC=com", ldap.SCOPE_SUBTREE, ldap.SCOPE_ONELEVEL, "(mail=%(user)s)")
AUTH_LDAP_E_USER_ATTR_MAP = AUTH_LDAP_USER_ATTR_MAP
AUTH_LDAP_E_ALWAYS_UPDATE_USER = AUTH_LDAP_ALWAYS_UPDATE_USER

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

backends.py

from django_auth_ldap.backend import LDAPBackend, _LDAPUser

class LDAPEmailBackend(LDAPBackend):
    settings_prefix = "AUTH_LDAP_E_"

    def get_or_create_user(self, email, ldap_user):

    model = self.get_user_model()
    username_field = getattr(model, 'USERNAME_FIELD', 'username')

    kwargs = {
        username_field + '__iexact': ldap_user.attrs['uid'][0],
        'defaults': {
         username_field: ldap_user.attrs['uid'][0].lower(),
         'email': email
        }
    }

    return model.objects.get_or_create(**kwargs)

控制台给了我这个:

  

search_s(' DC = sbvg,DC = ch',1,'(uid =%(user)s)')返回0个对象:   ipa@sbvg.ch的身份验证失败:无法将用户名映射到DN。   在验证ipa@sbvg.ch时遇到LDAPError:SERVER_DOWN({' desc':u"无法联系LDAP服务器"},)

如果您有任何想法,请不要犹豫发布。

3 个答案:

答案 0 :(得分:0)

我不知道这是否是答案,

LDAPSearch方法的作用域参数过多。范围需要一个位置参数。

AUTH_LDAP_E_USER_SEARCH = LDAPSearch("DC=domain,DC=com", ldap.SCOPE_SUBTREE, ldap.SCOPE_ONELEVEL, "(mail=%(user)s)")

reference

答案 1 :(得分:0)

在LDAP身份验证之后,我使用电子邮件地址而不是用户名成功登录了Django。 这就是需要的。

  1. 您不需要创建其他后端。 (例如:您的情况下为LDAPEmailBackend)

  2. settings.py的内容应如下

    AUTH_LDAP_USER_SEARCH = LDAPSearch("DC=domain, DC=com", ldap.SCOPE_SUBTREE, "mail=%(user)s)")
    
    AUTH_LDAP_USER_ATTR_MAP = { 
          'first_name': 'givenName',
          'last_name': 'sn',
          'email': 'mail',
    }
    
    AUTHENTICATION_BACKENDS = ( 
           'django_auth_ldap.backend.LDAPBackend',
           'django.contrib.auth.backends.ModelBackend',
    )
    

注意(一些其他信息):

  1. get_or_create_user()已弃用。如果您要使用它,请使用 get_or_build_user()

  2. 如果dn不包含电子邮件地址(这也许是服务器错误的原因),则可能需要摆脱 AUTH_LDAP_USER_DN_TEMPLATE ,因为AUTH_LDAP_USER_DN_TEMPLATE将寻找直接绑定

  3. 确保您的LDAP DIT(目录信息树)包含邮件条目:在DC = domain,DC = com范围内的what @ ever。

答案 2 :(得分:0)

在寻找在Django上同时使用用户名和电子邮件登录LDAP的方法时,我遇到了这个问题。这是我基于this gist找到的解决方案。下面的示例假定LDAP目录的用户电子邮件地址映射为“ mail”。我已经看到了将其命名为其他名称的情况,因此请确保您要通过正确的属性进行查询。

仅通过电子邮件登录

  1. 不需要其他后端

  2. 确保LDAP通过电子邮件查询用户,并且后端也通过电子邮件搜索Django用户。在settings.py

AUTH_LDAP_USER_SEARCH = LDAPSearch(
    "DC=domain,DC=com",
    ldap.SCOPE_SUBTREE,
    "uid=%(user)s)"
)

AUTH_LDAP_USER_QUERY_FIELD = 'email'

同时使用用户名和电子邮件登录

  1. 创建其他后端。
# -*- coding: utf-8 -*-
"""Custom authentication backend classes
"""
from __future__ import unicode_literals

from django_auth_ldap.backend import LDAPBackend


class LDAPEmailBackend(LDAPBackend):
    settings_prefix = 'AUTH_LDAP_E_'
  1. settings.py应该如下
# other settings

AUTHENTICATION_BACKENDS = (
    'django_auth_ldap.backend.LDAPBackend',  # this will handle LDAP login with username as usual
    'your_app.backends.LDAPEmailBackend',  # this will handle LDAP login with email
    'django.contrib.auth.backends.ModelBackend',
    # additional authentication backends
)

# LDAP search by uid
AUTH_LDAP_USER_SEARCH = LDAPSearch(
    "DC=domain,DC=com",
    ldap.SCOPE_SUBTREE,
    "uid=%(user)s)"
)

# LDAP search by mail
AUTH_LDAP_E_USER_SEARCH = LDAPSearch(
    "DC=domain,DC=com",
    ldap.SCOPE_SUBTREE,
    "mail=%(user)s)"
)
AUTH_LDAP_FILTERSTR=(uid=%(user)s)
AUTH_LDAP_E_FILTERSTR=(mail=%(user)s)
AUTH_LDAP_USER_ATTR_MAP = {
    "username": "uid",
    "email": "mail"
}
AUTH_LDAP_E_USER_ATTR_MAP = AUTH_LDAP_USER_ATTR_MAP  # we can use the same attr mapping
AUTH_LDAP_E_USER_QUERY_FIELD = "email"  # make sure it searches Django users by email

# other LDAP settings can have the same value for both backends, like _USER_ATTR_MAP above

# other settings

在Django 3.1.1 / Python 3.8.5和Django 1.11.27 / Python 2.7.12中进行了测试