使用python + ldap对活动目录进行身份验证
如何使用Python + LDAP针对AD进行身份验证。我目前正在使用python-ldap库,它所产生的只是眼泪。
我什至不能绑定执行一个简单的查询:
import sys import ldap Server = "ldap://my-ldap-server" DN, Secret, un = sys.argv[1:4] Base = "dc=mydomain,dc=co,dc=uk" Scope = ldap.SCOPE_SUBTREE Filter = "(&(objectClass=user)(sAMAccountName="+un+"))" Attrs = ["displayName"] l = ldap.initialize(Server) l.protocol_version = 3 print l.simple_bind_s(DN, Secret) r = l.search(Base, Scope, Filter, Attrs) Type,user = l.result(r,60) Name,Attrs = user[0] if hasattr(Attrs, 'has_key') and Attrs.has_key('displayName'): displayName = Attrs['displayName'][0] print displayName sys.exit()
使用[email protected] password username
运行此命令会给我两个错误之一:
"无效的凭据"当我输入错误或者故意使用错误的凭据时,它将无法通过身份验证。
ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 52e, vece', 'desc': 'Invalid credentials'}
或者
ldap.OPERATIONS_ERROR: {'info': '00000000: LdapErr: DSID-0C090627, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, vece', 'desc': 'Operations error'}
我缺少正确绑定的东西吗?
我在fedora和Windows上遇到了相同的错误。
解决方案
我不见了
l.set_option(ldap.OPT_REFERRALS, 0)
从init开始。
使用专有名称登录系统。"" CN =用户,CN =用户,DC = b2t,DC =本地"
它应该可以在任何LDAP系统上使用,包括AD
如果我们愿意使用pywin32,则可以使用来自Python的Win32调用。这是我们在CherryPy Web服务器中执行的操作:
import win32security token = win32security.LogonUser( username, domain, password, win32security.LOGON32_LOGON_NETWORK, win32security.LOGON32_PROVIDER_DEFAULT) authenticated = bool(token)
我看到我们对@Johan Buret的有关DN无法解决问题的评论,但我也认为这是我们应该研究的内容。
以示例为例,AD中默认管理员帐户的DN为:
cn =管理员,cn =用户,dc = mydomain,dc = co,dc = uk,请尝试一下。
这对我有用,l.set_option(ldap.OPT_REFERRALS,0)是访问ActiveDirectory的关键。此外,我认为我们应该在完成脚本之前添加" con.unbind()"以关闭连接。
如果这是用于经过身份验证的广告用户的Webapp的一部分,则可能会引起这个问题。
我试图添加
l.set_option(ldap.OPT_REFERRALS, 0)
但是Python不会挂起,而是挂起了,不再响应任何内容,而不是错误。也许我在构建搜索查询时出错,搜索的基础部分是什么?我使用的是与DN相同的简单绑定(哦,我不得不做l.simple_bind
,而不是l.simple_bind_s
):
import ldap local = ldap.initialize("ldap://127.0.0.1") local.simple_bind("CN=staff,DC=mydomain,DC=com") #my pc is not actually connected to this domain result_id = local.search("CN=staff,DC=mydomain,DC=com", ldap.SCOPE_SUBTREE, "cn=foobar", None) local.set_option(ldap.OPT_REFERRALS, 0) result_type, result_data = local.result(result_id, 0)
我正在使用AD LDS,并且该实例已为当前帐户注册。