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

内网Django Web应用集成Active Directory实现免密登录及信息获取咨询

实现Django内网AD免密登录及用户信息获取

咱们要搞定的是内网环境下基于Kerberos/NTLM的免密登录——让已经登录AD域的用户打开网站时自动完成认证,不用重复输密码,同时还要拉取他们的AD详细信息。下面是一步步可落地的方案:

一、先搭好核心依赖

先安装几个关键的Python包,这些是实现功能的基础:

  • django-auth-kerberos:专门处理Kerberos认证,是免密登录的核心
  • ldap3:用来连接AD服务器,查询用户的详细属性(部门、邮箱、职位等)
  • pywin32(如果Django服务器是Windows系统):辅助处理Windows环境下的Kerberos相关操作

用pip一键安装:

pip install django-auth-kerberos ldap3 pywin32

二、配置Kerberos认证(实现免密登录)

1. 服务器端配置Kerberos客户端

如果是Linux服务器:

  • 先装Kerberos工具包:sudo apt-get install krb5-user
  • 编辑/etc/krb5.conf,填入你的AD域信息:
[libdefaults]
    default_realm = YOUR_DOMAIN.COM
    dns_lookup_realm = true
    dns_lookup_kdc = true

[realms]
    YOUR_DOMAIN.COM = {
        kdc = ad.your_domain.com  # AD服务器的KDC地址
        admin_server = ad.your_domain.com
    }

[domain_realm]
    .your_domain.com = YOUR_DOMAIN.COM
    your_domain.com = YOUR_DOMAIN.COM

如果是Windows服务器:

确保服务器已经加入AD域,或者至少能通过DNS正常解析到AD的KDC服务器。

2. 创建AD服务主体并生成keytab文件

这一步是让Django服务能和AD的Kerberos系统互认:

  • 在AD服务器上,用管理员权限运行CMD,注册服务主体名称(SPN):
setspn -A HTTP/your-django-server.your_domain.com YOUR_DOMAIN\django_service_account

(django_service_account是你为Django服务创建的AD账号,也可以用现有账号)

  • 生成keytab文件(Django服务用来验证身份的密钥文件):
ktpass /princ HTTP/your-django-server.your_domain.com@YOUR_DOMAIN.COM /mapuser YOUR_DOMAIN\django_service_account /pass * /out django.keytab /ptype KRB5_NT_PRINCIPAL

把生成的django.keytab传到Django服务器上,给运行Django的用户设置读取权限。

3. 配置Django的settings.py

在项目的settings.py里添加认证后端和Kerberos相关配置:

# 追加认证后端,优先用Kerberos
AUTHENTICATION_BACKENDS = [
    'django_auth_kerberos.backends.KerberosBackend',
    'django.contrib.auth.backends.ModelBackend',  # 保留默认后端方便测试
]

# Kerberos核心配置
KERBEROS_REALM = 'YOUR_DOMAIN.COM'
KERBEROS_SERVICE_PRINCIPAL = 'HTTP/your-django-server.your_domain.com@YOUR_DOMAIN.COM'
KERBEROS_KEYTAB = '/path/to/django.keytab'  # Linux路径,Windows用'C:\\django.keytab'

# 可选:自动创建不存在的Django用户
KERBEROS_CREATE_USER = True
KERBEROS_USERNAME_SUFFIX = '@YOUR_DOMAIN.COM'  # 去掉域名后缀,比如把user@DOMAIN.COM变成user

4. 添加认证中间件

在settings.py的MIDDLEWARE列表里加入Negotiate中间件,让Django能处理客户端的Kerberos请求:

MIDDLEWARE = [
    # ... 其他原有中间件
    'django_auth_kerberos.middleware.NegotiateMiddleware',
]

三、获取AD用户详细信息

用户通过Kerberos认证后,我们可以用ldap3连接AD服务器,查询用户的各类详情。

1. 编写AD查询工具函数

在项目里新建一个工具文件(比如ad_utils.py),封装查询逻辑:

from ldap3 import Server, Connection, ALL, SUBTREE
from django.conf import settings

def get_ad_user_details(username):
    # 连接AD服务器
    ad_server = Server(settings.AD_SERVER, get_info=ALL)
    conn = Connection(
        ad_server,
        user=f'{settings.AD_SERVICE_ACCOUNT}@{settings.AD_REALM}',
        password=settings.AD_SERVICE_PASSWORD,
        auto_bind=True
    )

    # 查询用户属性,过滤条件和属性列表可根据你的AD结构调整
    search_filter = f'(sAMAccountName={username})'
    attributes = ['cn', 'mail', 'department', 'telephoneNumber', 'title', 'memberOf']
    conn.search(
        search_base=settings.AD_SEARCH_BASE,
        search_filter=search_filter,
        search_scope=SUBTREE,
        attributes=attributes
    )

    if conn.entries:
        user_entry = conn.entries[0]
        return {
            'full_name': user_entry.cn.value,
            'email': user_entry.mail.value if hasattr(user_entry, 'mail') else None,
            'department': user_entry.department.value if hasattr(user_entry, 'department') else None,
            'phone': user_entry.telephoneNumber.value if hasattr(user_entry, 'telephoneNumber') else None,
            'title': user_entry.title.value if hasattr(user_entry, 'title') else None,
            'groups': [group.split(',')[0].split('=')[1] for group in user_entry.memberOf] if hasattr(user_entry, 'memberOf') else []
        }
    return None

2. 在settings.py里添加AD查询配置

AD_SERVER = 'ad.your_domain.com'  # AD服务器地址
AD_REALM = 'YOUR_DOMAIN.COM'
AD_SERVICE_ACCOUNT = 'django_service_account'  # 用来查询AD的服务账号
AD_SERVICE_PASSWORD = 'your_service_account_password'
AD_SEARCH_BASE = 'DC=your_domain,DC=com'  # AD的搜索根节点,比如域是your_domain.com就填这个

3. 在视图中调用展示

比如在用户个人中心视图里:

from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from .ad_utils import get_ad_user_details

@login_required
def user_profile(request):
    ad_details = get_ad_user_details(request.user.username)
    return render(request, 'profile.html', {'ad_details': ad_details})

然后在模板profile.html里展示信息:

<h2>你的AD账户信息</h2>
{% if ad_details %}
    <p>姓名: {{ ad_details.full_name }}</p>
    <p>邮箱: {{ ad_details.email }}</p>
    <p>部门: {{ ad_details.department }}</p>
    <p>职位: {{ ad_details.title }}</p>
    <p>所属组: {{ ad_details.groups|join:', ' }}</p>
{% else %}
    <p>暂时无法获取AD信息,请联系管理员</p>
{% endif %}

四、测试与注意事项

  • 确保客户端和Django服务器在同一个AD域或信任域内,且客户端已登录AD账号
  • 现代浏览器(如Chrome)默认限制HTTP下的Negotiate认证,生产环境建议部署HTTPS;测试时可在Chrome的chrome://net-internals/#hsts里添加服务器域名
  • 如果Kerberos认证失败,可查看Django日志,或用kinit命令测试服务账号的票据获取是否正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:54:35