使用python + ldap对活动目录进行身份验证

时间:2008-09-26 16:08:11

标签: python authentication active-directory 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()

使用myusername@mydomain.co.uk password username运行此操作会给我带来两个错误之一:

Invalid Credentials - 当我输入错误或故意使用错误的凭据时,它无法进行身份验证。

  

ldap.INVALID_CREDENTIALS:{'info':'80090308:LdapErr:DSID-0C090334,评论:AcceptSecurityContext错误,数据52e,vece','desc':'凭证无效'}

  

ldap.OPERATIONS_ERROR:{'info':'00000000:LdapErr:DSID-0C090627,注释:为了执行此操作,必须在连接上完成成功绑定。,data 0,vece','desc': '操作错误'}

我错过了什么来正确绑定?

我在fedora和windows上遇到了同样的错误。

11 个答案:

答案 0 :(得分:44)

我不见了

l.set_option(ldap.OPT_REFERRALS, 0)

来自初学者。

答案 1 :(得分:25)

如果您愿意使用pywin32,则可以使用Python的Win32调用。这就是我们在CherryPy Web服务器中所做的事情:

import win32security
token = win32security.LogonUser(
    username,
    domain,
    password,
    win32security.LOGON32_LOGON_NETWORK,
    win32security.LOGON32_PROVIDER_DEFAULT)
authenticated = bool(token)

答案 2 :(得分:7)

这对我有用, l.set_option(ldap.OPT_REFERRALS,0)是访问ActiveDirectory的关键。此外,我认为你应该添加一个“con.unbind()”,以便在完成脚本之前关闭连接。

答案 3 :(得分:5)

这是一些适合我的简单代码。

import ldap  # run 'pip install python-ldap' to install ldap module.
conn = ldap.open("ldaphost.company.com")
conn.simple_bind_s("myuser@company.com", "mypassword")

这是基于previous answer

答案 4 :(得分:3)

如果您安装了Kerberos并与AD通信,例如安装并运行Centrify Express,您可能只使用python-kerberos。 E.g。

import kerberos
kerberos.checkPassword('joe','pizza','krbtgt/x.pizza.com','X.PIZZA.COM')`

将返回True,用户'joe'在Kerberos领域X.PIZZA.COM中有密码'pizza'。 (通常,我认为,后者与AD域的名称相同)

答案 5 :(得分:2)

我看到你对@Johan Buret的评论DN没有解决你的问题,但我也相信这是你应该研究的。

根据您的示例,AD中默认管理员帐户的DN将为: cn = Administrator,cn = Users,dc = mydomain,dc = co,dc = uk - 请试试。

答案 6 :(得分:1)

我尝试添加

  

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,并且该实例已在当前帐户中注册。

答案 7 :(得分:1)

我遇到了同样的问题,但是关于密码编码

.encode('iso-8859-1')

解决了这个问题。

答案 8 :(得分:1)

基于出色的ldap3 tutorial

>>> from ldap3 import Server, Connection, ALL, NTLM
>>> server = Server('server_name_or_ip', get_info=ALL)
>>> conn = Connection(server, user="user_name", password="password", auto_bind=True)
>>> conn.extend.standard.who_am_i()
>>> server.info

我在Python3中完成了上述操作,但是应该与Python 2兼容。

答案 9 :(得分:0)

使用专有名称登录您的系统。"CN=Your user,CN=Users,DC=b2t,DC=local" 它应该适用于任何LDAP系统,包括AD

答案 10 :(得分:0)

我从simple_bind_s()更改为bind()就可以了。