使用 python + ldap 对活动目录进行身份验证
Posted
技术标签:
【中文标题】使用 python + ldap 对活动目录进行身份验证【英文标题】:Authenticating against active directory using python + ldap 【发布时间】:2010-09-13 12:24:07 【问题描述】:如何使用 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, 注释:为了执行此操作,必须在连接上成功绑定。数据 0, vece', 'desc': '操作错误'
我错过了什么才能正确绑定?
我在 fedora 和 windows 上遇到同样的错误。
【问题讨论】:
“……它所产生的只是眼泪。” tears 是否与 Bears 或 Beers 押韵? 【参考方案1】:我错过了
l.set_option(ldap.OPT_REFERRALS, 0)
从一开始。
【讨论】:
此错误的根本原因是您在初始响应中有引用并且 Windows LDAP 代码没有将凭据发送到引用服务器。如果您使用 kerberos 凭据,它应该可以工作。 我有不同的症状,但同样的选项解决了我的问题。总结在一篇博文中:chaverma.com/blog/index.php/2013/06/… 不确定是否相关,但我遇到了同样的问题,似乎 1729 的解决方案做了一些事情 - 但有时 LDAP 服务器会立即回答 INVALID CREDENTIALS。一段时间后它会平静下来并再次工作。【参考方案2】:如果您愿意使用 pywin32,则可以使用 Python 中的 Win32 调用。这就是我们在 CherryPy 网络服务器中所做的:
import win32security
token = win32security.LogonUser(
username,
domain,
password,
win32security.LOGON32_LOGON_NETWORK,
win32security.LOGON32_PROVIDER_DEFAULT)
authenticated = bool(token)
【讨论】:
简单干净!谢谢! 这个解决方案在 Python Flask 应用程序中为我工作,同时在限制性 NTLM 公司代理后面。其他一些基于 LDAP 的选项根本不起作用。【参考方案3】:这对我有用,l.set_option(ldap.OPT_REFERRALS, 0) 是访问 ActiveDirectory 的关键。此外,我认为您应该添加一个“con.unbind()”以便在完成脚本之前关闭连接。
【讨论】:
来自python-ldap documentation:LDAPObject
的实例由initialize()
返回。删除 LDAP 对象时,连接会自动解除绑定并关闭。
你关闭了会话,而不是连接。【参考方案4】:
这里有一些对我有用的简单代码。
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。
【讨论】:
这行不通了,你会收到AttributeError: module 'ldap' has no attribute 'open'
【参考方案5】:
如果您安装了 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 域的名称相同)
【讨论】:
【参考方案6】:我看到你对@Johan Buret 的评论,关于 DN 没有解决你的问题,但我也相信这是你应该研究的。
以您的示例为例,AD 中默认管理员帐户的 DN 将是: cn=Administrator,cn=Users,dc=mydomain,dc=co,dc=uk - 请尝试一下。
【讨论】:
【参考方案7】:基于优秀的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 兼容。
【讨论】:
【参考方案8】:我尝试添加
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,并且该实例已为当前帐户注册。
【讨论】:
【参考方案9】:我也有同样的问题,但是是关于密码编码的
.encode('iso-8859-1')
解决了这个问题。
【讨论】:
【参考方案10】:使用专有名称登录您的系统。"CN=Your user,CN=Users,DC=b2t,DC=local"
它应该适用于任何 LDAP 系统,包括 AD
【讨论】:
【参考方案11】:对我来说,从 simple_bind_s()
更改为 bind()
成功了。
【讨论】:
以上是关于使用 python + ldap 对活动目录进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章
使用LDAP登录模块进行Teiid VDB数据虚拟化的身份验证失败
Grails - Spring 安全 ldap 活动目录身份验证 - 凭据错误错误
Java Active Directory LDAP - 使用密码哈希对用户进行身份验证