如何基于Django搭建用户自助修改Active Directory密码的网页
绝对可以实现!我之前帮公司搭建过一模一样的自助域密码重置系统,帮管理员省了超多处理重置请求的时间。下面给你一步步拆解实现方案:
核心思路与依赖选择
要让Django对接Active Directory,我们需要用Python的LDAP操作库来和AD交互。这里推荐ldap3——它是现代、跨平台的LDAP客户端,比老旧的pyad更灵活,而且不需要依赖Windows环境。
实现步骤与关键代码
1. 安装依赖
先把需要的包装起来:
pip install ldap3 django
2. 配置AD连接信息
在Django的settings.py里添加AD相关配置(记得把占位符换成你的实际信息):
# settings.py AD_SERVER = 'your-ad-server.example.com' # AD服务器地址或域名 AD_DOMAIN = 'EXAMPLE' # 域前缀(比如你的域是example.com,这里填EXAMPLE) AD_SERVICE_ACCOUNT = 'ad_service_account@example.com' # 有修改密码权限的服务账号 AD_SERVICE_PASSWORD = 'your-service-account-password' # 服务账号密码 AD_SEARCH_BASE = 'OU=CompanyUsers,DC=example,DC=com' # 用户所在的OU的LDAP路径
3. 编写AD操作工具类
新建一个ad_utils.py文件,封装AD验证和密码修改的逻辑:
from ldap3 import Server, Connection, ALL, MODIFY_REPLACE from django.conf import settings def authenticate_ad_user(username, password): """验证用户当前AD密码是否正确""" server = Server(settings.AD_SERVER, get_info=ALL) try: # 用用户自己的账号密码绑定AD,验证身份 conn = Connection(server, user=f"{settings.AD_DOMAIN}\\{username}", password=password, auto_bind=True) conn.unbind() return True except Exception as e: print(f"身份验证失败: {str(e)}") return False def change_ad_user_password(username, new_password): """修改AD用户密码""" server = Server(settings.AD_SERVER, get_info=ALL) try: # 用服务账号连接AD(必须有修改用户密码的权限) conn = Connection(server, user=settings.AD_SERVICE_ACCOUNT, password=settings.AD_SERVICE_PASSWORD, auto_bind=True) # 搜索用户的LDAP区分名(DN) conn.search( search_base=settings.AD_SEARCH_BASE, search_filter=f"(sAMAccountName={username})", attributes=['distinguishedName'] ) if not conn.entries: conn.unbind() return False, "未找到该域账号" user_dn = conn.entries[0].distinguishedName.value # AD要求密码转成UTF-16LE字节串,并用双引号包裹 encoded_password = f'"{new_password}"'.encode('utf-16-le') # 执行密码修改操作 conn.modify( user_dn, {'unicodePwd': [(MODIFY_REPLACE, [encoded_password])]} ) if conn.result['result'] == 0: conn.unbind() return True, "密码修改成功!" else: conn.unbind() return False, f"修改失败: {conn.result['description']}" except Exception as e: return False, f"连接AD服务器失败: {str(e)}"
4. 编写Django视图与表单
在views.py里处理用户的密码修改请求:
from django.shortcuts import render, redirect from django.contrib import messages from django import forms from .ad_utils import authenticate_ad_user, change_ad_user_password # 定义密码修改表单 class PasswordChangeForm(forms.Form): username = forms.CharField(label='域账号', max_length=50) current_password = forms.CharField(label='当前密码', widget=forms.PasswordInput) new_password = forms.CharField(label='新密码', widget=forms.PasswordInput) confirm_new_password = forms.CharField(label='确认新密码', widget=forms.PasswordInput) def clean(self): cleaned_data = super().clean() new_pwd = cleaned_data.get('new_password') confirm_pwd = cleaned_data.get('confirm_new_password') # 验证两次密码一致 if new_pwd != confirm_pwd: raise forms.ValidationError("新密码与确认密码不匹配") # 这里可以加和AD一致的密码复杂度验证(比如长度≥8、包含大小写等) if len(new_pwd) < 8: raise forms.ValidationError("密码长度至少为8位") return cleaned_data def password_change(request): if request.method == 'POST': form = PasswordChangeForm(request.POST) if form.is_valid(): username = form.cleaned_data['username'] current_pwd = form.cleaned_data['current_password'] new_pwd = form.cleaned_data['new_password'] # 先验证当前密码是否正确 if authenticate_ad_user(username, current_pwd): # 验证通过,执行密码修改 success, msg = change_ad_user_password(username, new_pwd) if success: messages.success(request, msg) return redirect('password_change') else: messages.error(request, msg) else: messages.error(request, "当前密码不正确,请重新输入") else: form = PasswordChangeForm() return render(request, 'password_change.html', {'form': form})
5. 编写前端模板
新建templates/password_change.html页面:
<!DOCTYPE html> <html> <head> <title>域密码自助修改</title> <style> .success { color: green; } .error { color: red; } </style> </head> <body> <h1>域密码自助修改</h1> {% if messages %} {% for message in messages %} <div class="{{ message.tags }}">{{ message }}</div> {% endfor %} {% endif %} <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">确认修改</button> </form> </body> </html>
关键注意事项
- 服务账号权限:一定要确保你用的AD服务账号有“重置用户密码”的权限,可以在AD管理器里给该账号分配对应OU的权限。
- 安全防护:
- 网站必须用HTTPS部署,避免密码明文传输;
- 可以添加验证码功能,防止暴力破解;
- 记录所有密码修改操作日志,方便审计。
- 密码策略对齐:前端/后端的密码复杂度验证要和AD的域密码策略保持一致,避免用户输入不符合要求的密码导致修改失败。
内容的提问来源于stack exchange,提问作者KalicXing Njenga
相关产品推荐
相关产品推荐

