如何使用 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
运行此命令会出现以下两个错误之一:
Invalid Credentials
- 当我输入错误或故意使用错误的凭据时,它无法进行身份验证。
ldap.INVALID_CREDENTIALS:{'info':'80090308:LdapErr:DSID-0C090334,注释:AcceptSecurityContext错误,数据52e,vece','desc':'无效凭据'}
或者
ldap.OPERATIONS_ERROR: {'info': '00000000: LdapErr: DSID-0C090627, comment: 为了执行此操作,必须在连接上完成成功的绑定。, data 0, vece', 'desc': '操作错误'}
为了正确绑定我错过了什么?
我在 Fedora 和 Windows 上遇到同样的错误。
我失踪了
l.set_option(ldap.OPT_REFERRALS, 0)
从 init 开始。
如果您愿意使用 pywin32,则可以使用 Python 中的 Win32 调用。这就是我们在 CherryPy Web 服务器中所做的事情:
import win32security
token = win32security.LogonUser(
username,
domain,
password,
win32security.LOGON32_LOGON_NETWORK,
win32security.LOGON32_PROVIDER_DEFAULT)
authenticated = bool(token)
这对我有用,l.set_option(ldap.OPT_REFERRALS, 0)是访问ActiveDirectory的关键。此外,我认为您应该添加一个“con.unbind()”以便在完成脚本之前关闭连接。
这是一些适合我的简单代码。
import ldap # run 'pip install python-ldap' to install ldap module.
conn = ldap.open("ldaphost.company.com")
conn.simple_bind_s("[email protected]", "mypassword")
这是基于之前的答案。
基于优秀的 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兼容。
如果您安装了 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 域的名称相同)
我看到您对 @Johan Buret 的评论,称 DN 无法解决您的问题,但我也相信这就是您应该研究的内容。
根据您的示例,AD 中默认管理员帐户的 DN 将为: cn=管理员,cn=用户,dc=mydomain,dc=co,dc=uk - 请尝试一下。
我尝试添加
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,并且该实例是为当前帐户注册的。
我有同样的问题,但它与密码编码有关
.encode('iso-8859-1')
问题解决了。
使用专有名称登录您的系统。
"CN=Your user,CN=Users,DC=b2t,DC=local"
它应该适用于任何 LDAP 系统,包括 AD
对我来说,从
simple_bind_s()
更改为 bind()
就成功了。
使用 ldap3 更容易使用 python 实现 LDAP。我已经使用过几次了,看起来非常简单和安全。官方文档更容易理解和遵循。 https://ldap3.readthedocs.io/en/latest/