LDAP搜索过滤器特殊字符转义:查询含特殊字符用户时出错
LDAP查询含特殊字符用户时的转义问题解决
问题描述
使用Python的ldap3库查询Active Directory指定组成员的sAMAccountName时,遇到CN包含()、,、?、#、é等特殊字符的用户,会触发LDAPInvalidFilterError: malformed filter错误。原代码如下:
base = "CN=mygroup,OU=Security Group,OU=Resources,OU=Global,DC=Domain,DC=com" ldap_conn.search(search_base = base,search_filter = '(objectClass=group)',search_scope='SUBTREE',attributes = ['member']) for entry in ldap_conn.entries: for member in entry.member.values: ldap_conn.search(search_base='OU=Global,DC=Domain,DC=com',search_filter=f'(distinguishedName={member})',attributes=['sAMAccountName']) user_sAMAccountName = ldap_conn.entries[0].sAMAccountName.values print(user_sAMAccountName)
错误信息:
ldap_conn.search(search_base='DC=DOMAIN,DC=com',search_filter=f'(distinguishedName={member})',attributes=['sAMAccountName']) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/ldap3/core/connection.py", line 838, in search request = search_operation(search_base, File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/ldap3/operation/search.py", line 371, in search_operation request['filter'] = compile_filter(parse_filter(search_filter, schema, auto_escape, auto_encode, validator, check_names).elements[0]) # parse the searchFilter string and compile it starting from the root node File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/ldap3/operation/search.py", line 214, in parse_filter raise LDAPInvalidFilterError('malformed filter') ldap3.core.exceptions.LDAPInvalidFilterError: malformed filter
解决方法
LDAP查询过滤器中特殊字符必须按RFC 4515规范转义,ldap3库提供了内置方案,无需手动处理:
方法1:使用escape_filter_chars函数
调用库内置的转义函数处理member变量:
from ldap3.utils.conv import escape_filter_chars base = "CN=mygroup,OU=Security Group,OU=Resources,OU=Global,DC=Domain,DC=com" ldap_conn.search(search_base = base,search_filter = '(objectClass=group)',search_scope='SUBTREE',attributes = ['member']) for entry in ldap_conn.entries: for member in entry.member.values: # 转义distinguishedName中的特殊字符 escaped_member = escape_filter_chars(member) ldap_conn.search(search_base='OU=Global,DC=Domain,DC=com',search_filter=f'(distinguishedName={escaped_member})',attributes=['sAMAccountName']) user_sAMAccountName = ldap_conn.entries[0].sAMAccountName.values print(user_sAMAccountName)
方法2:启用自动转义参数
在search方法中设置auto_escape=True,让库自动处理过滤器中的特殊字符:
base = "CN=mygroup,OU=Security Group,OU=Resources,OU=Global,DC=Domain,DC=com" ldap_conn.search(search_base = base,search_filter = '(objectClass=group)',search_scope='SUBTREE',attributes = ['member']) for entry in ldap_conn.entries: for member in entry.member.values: # 启用auto_escape自动转义特殊字符 ldap_conn.search(search_base='OU=Global,DC=Domain,DC=com',search_filter=f'(distinguishedName={member})',attributes=['sAMAccountName'], auto_escape=True) user_sAMAccountName = ldap_conn.entries[0].sAMAccountName.values print(user_sAMAccountName)
补充说明
需要转义的LDAP特殊字符包括*、(、)、\、NUL,以及DN中出现的,、#、?等,escape_filter_chars会自动处理所有规范内的转义需求,同时也能正确处理带重音的字符(如é)的编码问题。
内容的提问来源于stack exchange,提问作者shlco
相关产品推荐
相关产品推荐

