You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django LDAP认证明文传输问题:如何在TCP/389下实现安全认证?

解决方案:用NTLM认证替代简单绑定,避免LDAP明文传密码

你的场景确实很常见——AD没开LDAPS,又没有权限修改配置,那NTLM认证是最适合的方案,它能在389端口上安全传输认证信息,不需要LDAPS或START_TLS,而且可以通过自定义django_auth_ldap后端轻松实现。

核心思路

AD原生支持NTLM认证,它采用挑战-响应机制,不会明文传输密码。我们只需要重写django_auth_ldap的绑定逻辑,把默认的简单绑定换成NTLM绑定即可。

具体代码修改步骤

  1. 创建自定义LDAP后端
    在你的Django项目里(比如某个app的backends.py文件),添加以下代码:
import ldap
from django_auth_ldap.backend import LDAPBackend

class NTLMLDAPBackend(LDAPBackend):
    def bind(self, connection):
        # 用NTLM协议绑定AD服务器
        ntlm_username = self.settings.BIND_DN
        password = self.settings.BIND_PASSWORD
        
        # 调用python-ldap的NTLM绑定方法
        connection.simple_bind_s(ntlm_username, password)
  1. 调整LDAP配置
    修改你的settings.py里的LDAP相关配置,重点调整BIND_DN格式和认证后端:
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, LDAPGroupQuery

AUTH_LDAP_GLOBAL_OPTIONS = {
    ldap.OPT_X_TLS_REQUIRE_CERT: False,
    ldap.OPT_REFERRALS: False,
    ldap.OPT_PROTOCOL_VERSION: ldap.VERSION3,  # 必须启用LDAPv3才能支持NTLM
}

# 注意:这里的BIND_DN要改成NTLM格式,比如 DOMAIN\sam_account_name 或者 user@domain.local
# 不再使用LDAP的DN格式(CN=xxx,OU=xxx...)
AUTH_LDAP_BIND_DN = "YOUR_DOMAIN\\your_bind_user"
AUTH_LDAP_BIND_PASSWORD = credentials.adlogin['pass']
AUTH_LDAP_SERVER_URI = "ldap://x.x.x.x"

# 以下配置保持不变
AUTH_LDAP_USER_SEARCH = LDAPSearch("OU=xxx,DC=xxx,DC=xxx,DC=coxxm", ldap.SCOPE_SUBTREE, "(sAMAccountName=%(user)s)")
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=groups,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)")
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()
AUTH_LDAP_REQUIRE_GROUP = (
    LDAPGroupQuery("CN=xx-xx,OU=xx,OU=xxx,,DC=xx,DC=xxx,DC=xx") | LDAPGroupQuery("CN=xx-xx,OU=xx,OU=xxx,,DC=xx,DC=xxx,DC=xx")
)
AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail"
}
SESSION_COOKIE_AGE = 15*60

# 替换为自定义的NTLM后端
AUTHENTICATION_BACKENDS = [
    'your_app_name.backends.NTLMLDAPBackend',  # 替换成你实际的app路径
    'django.contrib.auth.backends.ModelBackend',
]

关键注意事项

  • BIND_DN格式:必须用DOMAIN\sam_account_name或者user@domain.local的格式,不能再用原来的LDAP DN(比如CN=xxx...),因为NTLM认证是基于SAM账户名的。
  • python-ldap依赖:确保你的python-ldap安装包支持NTLM。如果是用pip安装的,一般默认支持;如果是系统包,可能需要安装带NTLM支持的libldap开发库(比如Ubuntu的libldap2-dev)。
  • Kerberos的备选方案:Kerberos也能实现安全认证,但配置更复杂——需要和AD的KDC服务器同步时间、创建keytab文件,对于你的场景来说NTLM是更轻量的选择。

这样修改后,你的Django应用就能在389端口上安全地和AD做认证,不会明文传输密码了。

内容的提问来源于stack exchange,提问作者john_thats_me

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:14:24