2

我想使用运行时给出的 ldap url 打开到 ldap 目录的连接。例如 :

ldap://192.168.2.151/dc=directory,dc=example,dc=com

据我所知,它是有效的。Python-ldap url 解析器ldapurl.LDAPUrl接受它。

url = 'ldap://192.168.2.151/dc=directory,dc=example,dc=com'
parsed_url = ldapurl.LDAPUrl(url)
parsed_url.dn
'dc=directory,dc=example,dc=com'

但是如果我用它来初始化一个 LDAPObject,我会得到一个ldap.LDAPError异常

ldap.initialize(url)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/ldap/functions.py", line 91, in initialize
    return LDAPObject(uri,trace_level,trace_file,trace_stack_limit)
  File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 70, in __init__
    self._l = ldap.functions._ldap_function_call(ldap._ldap_module_lock,_ldap.initialize,uri)
File "/usr/lib/python2.7/dist-packages/ldap/functions.py", line 63, in _ldap_function_call
  result = func(*args,**kwargs)
ldap.LDAPError: (0, 'Error')

我发现如果我手动编码dnurl 的一部分,它可以工作:

url = 'ldap://192.168.2.151/dc=directory%2cdc=example%2cdc=com'

#url still valid
parsed_url = ldapurl.LDAPUrl(url)
parsed_url.dn
'dc=directory,dc=example,dc=com'

#and will return a valid connection
ldap.initialize(url)
<ldap.ldapobject.SimpleLDAPObject instance at 0x1400098>

如何在ldap.initialize不自己编码部分 url 的情况下确保健壮的 url 处理?(恐怕无论如何都不会那么健壮)。

4

2 回答 2

1

您可以以编程方式对 URL 的最后一部分进行编码:

from urllib import quote       # works in Python 2.x
from urllib.parse import quote # works in Python 3.x

url = 'ldap://192.168.2.151/dc=directory,dc=paralint,dc=com'
idx = url.rindex('/') + 1
url[:idx] + quote(url[idx:], '=')
=> 'ldap://192.168.2.151/dc=directory%2Cdc=paralint%2Cdc=com'
于 2013-06-20T02:18:21.827 回答
1

可以使用LDAPUrl.unparse()方法来获取正确编码的 URI 版本,如下所示:

>>> import ldapurl
>>> url = ldapurl.LDAPUrl('ldap://192.168.2.151/dc=directory,dc=example,dc=com')
>>> url.unparse()
'ldap://192.168.2.151/dc%3Ddirectory%2Cdc%3Dparalint%2Cdc%3Dcom???'
>>> ldap.initialize(url.unparse())
<ldap.ldapobject.SimpleLDAPObject instance at 0x103d998>

并且LDAPUrl.unparse()不会重新编码已经编码的 url :

>>> url = ldapurl.LDAPUrl('ldap://example.com/dc%3Dusers%2Cdc%3Dexample%2Cdc%3Dcom%2F???')
>>> url.unparse()
'ldap://example.com/dc%3Dusers%2Cdc%3Dexample%2Cdc%3Dcom%2F???'

因此,您可以在程序必须处理的任何 ldap uri 上盲目使用它。

于 2013-07-16T03:55:58.290 回答