如何使用Python ldap3通过邮箱或用户ID实现LDAP认证?
实现邮箱/用户ID的LDAP认证方案
核心思路
先通过具备搜索权限的服务账号(或匿名连接)绑定LDAP服务器,根据用户输入的邮箱/用户ID搜索对应的用户DN,再用该DN和用户密码完成最终认证。
完整代码实现
from ldap3 import Server, Connection, ALL_ATTRIBUTES, escape_filter_chars def ldap_auth(user_input, password, ldap_server): # 1. 用服务账号绑定LDAP,搜索用户DN(若允许匿名搜索可跳过服务账号) service_dn = 'CN=LDAP Search Service,OU=Service Accounts,DC=mydc,DC=mydomain,DC=co,DC=uk' service_pwd = 'ServicePass123' server = Server(ldap_server, get_info=ALL_ATTRIBUTES) # 执行用户DN搜索 try: with Connection(server, user=service_dn, password=service_pwd, auto_bind=True) as search_conn: # 转义输入字符,防止LDAP注入 safe_input = escape_filter_chars(user_input) # 构造搜索过滤器:匹配邮箱或用户ID(这里假设用户ID对应sAMAccountName,需根据实际调整) search_filter = f'(|(mail={safe_input})(sAMAccountName={safe_input}))' # 搜索根节点,替换为你的LDAP用户所在的基础DN search_base = 'DC=mydc,DC=mydomain,DC=co,DC=uk' search_conn.search(search_base, search_filter, attributes=['distinguishedName']) if not search_conn.entries: return False, '未找到匹配用户' if len(search_conn.entries) > 1: return False, '找到多个重复用户' user_dn = search_conn.entries[0].distinguishedName.value except Exception as e: return False, f'搜索用户失败: {str(e)}' # 2. 用用户DN和密码完成认证 try: with Connection(server, user=user_dn, password=password, auto_bind=True): return True, '认证成功' except Exception as e: return False, f'认证失败: {str(e)}' # 使用示例 ldap_server_addr = 'ldap://your-ldap-server:389' # 生产环境建议用ldaps:// auth_result, msg = ldap_auth('john.doe@mydomain.co.uk', 'UserPass456', ldap_server_addr) print(auth_result, msg)
关键注意事项
- 权限配置:确保服务账号拥有搜索用户
mail、sAMAccountName、distinguishedName属性的权限;若LDAP允许匿名搜索,可直接匿名绑定(去掉服务账号相关代码)。 - 属性适配:用户ID对应的LDAP属性可能不是
sAMAccountName,比如部分系统用uid,需根据实际LDAP架构调整搜索过滤器中的属性名。 - 安全防护:生产环境必须使用
ldaps://加密连接;用escape_filter_chars处理用户输入,避免LDAP注入风险。
内容的提问来源于stack exchange,提问作者pee2pee
相关产品推荐
相关产品推荐

