我没有幸运地找到答案,所以就这样了。
当我使用python-ldap连接到AD服务器时,它似乎可以成功地用于某些功能,而不是其他功能。我的联系:
>>>import sys
>>>import ldap
>>>l = ldap.initialize("ldap://company.com:389")
>>>l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
>>>l.simple_bind_s("user@company.com","password")
(97, [], 1, [])
一些简单的谷歌搜索表明,97意味着成功,虽然成功的程度有点不稳定。但是,出于某种原因,我无法在状态代码1上找到任何内容。如果我在连接上运行一些ldap函数,其中一些可以正常运行,而另一些则不运行。
>>>l.whoami_s()
'u:COMPANY.COM\\user'
似乎返回正常,但
>>> base_dn = 'dc=company,dc=com'
>>> retrieveAttributes = ["uniquemember"]
>>> searchFilter = "cn=user"
>>> l.search_s(base_dn, ldap.SCOPE_SUBTREE,searchFilter,retrieveAttributes)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 552, in search_s
return self.search_ext_s(base,scope,filterstr,attrlist,attrsonly,None,None,timeout=self.timeout)
File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 546, in search_ext_s
return self.result(msgid,all=1,timeout=timeout)[1]
File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 458, in result
resp_type, resp_data, resp_msgid = self.result2(msgid,all,timeout)
File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 462, in result2
resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all,timeout)
File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 469, in result3
resp_ctrl_classes=resp_ctrl_classes
File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 476, in result4
ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
File "/home/user/.envs/scoring/local/lib/python2.7/site-packages/ldap/ldapobject.py", line 99, in _ldap_call
result = func(*args,**kwargs)
OPERATIONS_ERROR: {'info': '000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1', 'desc': 'Operations error'}
我很难理解为什么whoami会起作用,但搜索不会。我正在为用户使用域管理员,因此它不应该与目录的权限有任何关系。任何人都能解释一下吗?
答案 0 :(得分:11)
我得到了与你完全相同的错误,我所做的是在进行绑定之前添加这一行(如Christopher所建议的),l.set_option(ldap.OPT_REFERRALS,0),例如。
conn.protocol_version = ldap.VERSION3
conn.set_option(ldap.OPT_REFERRALS, 0)
conn.simple_bind_s(user, pw)
之后我与LDAP的连接工作正常。
答案 1 :(得分:4)
基于@Cas上面所说的,我只需要添加:
connection.set_option(ldap.OPT_REFERRALS,0)
看起来这是一个常见的问题,它被添加到python-ldap FAQ:
问:我的脚本绑定到MS Active Directory但是搜索操作 导致带有诊断的ldap.OPERATIONS_ERROR异常 消息文本&#34;为了执行此操作,成功绑定 必须在连接上完成。&#34;。这里发生了什么?
答:从域级别进行搜索时,MS AD会返回引荐 (搜索延续)一些对象指示给客户端 在哪里寻找这些对象。客户追踪推荐是一个 由于LDAPv3未指定要使用的凭据,因此概念已损坏 在追逐推荐时。 Windows客户端应该只是使用 他们的Windows凭据,但一般不起作用 追逐从任意LDAP接收并指向任意LDAP的引用 服务器。因此,每个默认的libldap会自动追逐 内部引用的匿名访问因MS AD而失败。 最好的办法就是关闭此行为:
l = ldap.initialize(&#39; ldap:// foobar&#39;)
l.set_option(ldap.OPT_REFERRALS,0)
答案 2 :(得分:1)
试试:
import ldap
connect = ldap.initialize("ldap://example.com")
connect.set_option(ldap.OPT_REFERRALS, 0)
try:
connect.simple_bind_s(login, password)
connect.search_s("dc=example,dc=com",
ldap.SCOPE_SUBTREE,
'userPrincipalName={}'.format(login),
['cn'])
except (ldap.INVALID_CREDENTIALS, ldap.OPERATIONS_ERROR):
return False
retrurn True
所以这里我们将 LDAP 与我们的凭据绑定,如果没有出现错误,我们尝试在 LDAP 中搜索我们用户的 CN。如果有一个空密码并且这是不正确的,这里将引发 OPERATIONS_ERROR,因为没有执行与凭据的实际绑定。
答案 3 :(得分:0)
如果在使用flask-simpleldap时出现此错误,则可以使用此oneliner:
app.config['LDAP_CUSTOM_OPTIONS'] = {l.OPT_REFERRALS: 0}
查看示例here。