94

如何使用 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, comment: AcceptSecurityContext error, data 52e, vece', 'desc': 'Invalid credentials'}

或者

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

我错过了什么才能正确绑定?

我在 Fedora 和 Windows 上遇到了同样的错误。

4

11 回答 11

50

我失踪了

l.set_option(ldap.OPT_REFERRALS, 0)

从一开始。

于 2008-09-26T16:18:18.320 回答
31

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

import win32security
token = win32security.LogonUser(
    username,
    domain,
    password,
    win32security.LOGON32_LOGON_NETWORK,
    win32security.LOGON32_PROVIDER_DEFAULT)
authenticated = bool(token)
于 2008-09-26T20:23:04.160 回答
7

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

于 2009-07-14T16:02:22.150 回答
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")

这是基于先前的答案

于 2013-08-16T21:32:24.373 回答
3

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

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

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

于 2011-08-01T18:46:53.913 回答
2

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

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

于 2008-09-30T14:36:49.713 回答
2

基于优秀的ldap3 教程

>>> 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 兼容。

于 2019-01-29T08:22:01.843 回答
1

我试图添加

l.set_option(ldap.OPT_REFERRALS, 0)

但不是错误,Python 只是挂起并且不再响应任何内容。也许我构建的搜索查询错误,搜索的 Base 部分是什么?我使用与简单绑定相同的 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,并且该实例已为当前帐户注册。

于 2010-10-13T04:11:36.473 回答
1

我有同样的问题,但它是关于密码编码

.encode('iso-8859-1')

解决了这个问题。

于 2016-07-13T10:01:51.073 回答
0

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

于 2008-09-26T17:14:23.147 回答
0

对我来说,从simple_bind_s()bind()做的伎俩。

于 2012-03-30T13:25:44.443 回答