如何使用python ldap3库获取通过邮箱查询到的AD用户的DN或登录名
基于python ldap3获取AD用户登录名的实现方案
核心逻辑
你已经可以通过邮箱查询到对应用户条目,不需要额外做复杂解析,只需要在查询时指定返回AD标准的登录名字段即可,AD中支持用于bind操作的用户标识有三类,都可以直接从查询结果中提取:
- 用户条目的DN(distinguishedName)
- 短格式登录名
sAMAccountName(通常搭配域前缀使用,格式为域名\登录名) - UPN格式登录名
userPrincipalName(通常为邮箱格式,可直接用于bind)
完整实现代码示例
1. 查询时指定返回登录属性
执行邮箱查询时提前把需要的登录字段加入返回属性列表即可:
from ldap3 import Server, Connection, SUBTREE # 初始化AD连接(使用已有查询权限的服务账号绑定即可) server = Server('AD服务器地址', get_info='ALL') conn = Connection(server, '服务账号DN', '服务账号密码', auto_bind=True) # 配置查询参数 search_base = 'AD根查询DN,例:DC=corp,DC=example,DC=com' input_mail = '用户输入的登录邮箱' search_filter = f'(& (mail={input_mail})(objectClass=organizationalPerson))' # 核心:attributes参数指定要返回的登录属性 conn.search( search_base, search_filter, search_scope=SUBTREE, attributes=['distinguishedName', 'sAMAccountName', 'userPrincipalName'] )
2. 提取登录标识
if len(conn.entries) == 1: user_entry = conn.entries[0] # 方案1:直接提取用户DN,可直接用于bind user_dn = user_entry.entry_dn # 方案2:提取短登录名,bind时格式为 域NetBIOS名\sAMAccountName,例:CORP\zhangsan sam_account = user_entry.sAMAccountName.value # 方案3:提取UPN登录名,可直接用于bind,例:zhangsan@corp.example.com upn_account = user_entry.userPrincipalName.value elif len(conn.entries) > 1: # 异常处理:同一邮箱对应多个AD账号,按你的业务规则处理即可 print("邮箱对应账号不唯一") else: print("未查询到对应用户")
3. 密码校验示例(bind操作)
用上面提取的任意一个标识都可以完成密码校验:
# 示例用DN做bind校验 auth_conn = Connection(server, user=user_dn, password="用户输入的密码") if auth_conn.bind(): print("登录校验成功") auth_conn.unbind() else: print("密码校验失败,错误信息:", auth_conn.result)
注意事项
上述方案适用于标准AD配置场景,如果你所在的域有自定义登录名字段,只需要在查询时把对应自定义字段加入attributes列表提取即可。
- 提前保证AD内邮箱字段唯一性,避免一个邮箱对应多个账号导致逻辑异常
- 用于查询的服务账号需要有对应OU的属性读取权限,否则会出现返回属性为空的问题
- 校验完成后及时调用
unbind()释放连接资源
内容的提问来源于stack exchange,提问作者EinEsellesEniE
相关产品推荐
相关产品推荐

