简体   繁体   English

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

[英]Authenticating against active directory using python + ldap

How do I authenticate against AD using Python + LDAP. 如何使用Python + LDAP对AD进行身份验证。 I'm currently using the python-ldap library and all it is producing is tears. 我目前正在使用python-ldap库,它所产生的就是眼泪。

I can't even bind to perform a simple query: 我甚至无法绑定执行简单的查询:

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()

Running this with myusername@mydomain.co.uk password username gives me one of two errors: 使用myusername@mydomain.co.uk password username运行此myusername@mydomain.co.uk password username给出了以下两个错误之一:

Invalid Credentials - When I mistype or intentionally use wrong credentials it fails to authenticate. Invalid Credentials - 当我输入错误或故意使用错误的凭据时,它无法进行身份验证。

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

Or 要么

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

What am I missing out to bind properly? 我错过了什么来正确绑定?

I am getting the same errors on fedora and windows. 我在fedora和windows上遇到了同样的错误。

I was missing 我失踪了

l.set_option(ldap.OPT_REFERRALS, 0)

From the init. 从init。

If you are open to using pywin32, you can use Win32 calls from Python. 如果您愿意使用pywin32,则可以使用Python的Win32调用。 This is what we do in our CherryPy web server: 这就是我们在CherryPy Web服务器中所做的事情:

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

That worked for me, l.set_option(ldap.OPT_REFERRALS, 0) was the key to access the ActiveDirectory. 这对我有用l.set_option(ldap.OPT_REFERRALS,0)是访问ActiveDirectory的关键。 Moreover, I think that you should add an "con.unbind()" in order to close the connection before finishing the script. 此外,我认为你应该添加一个“con.unbind()”,以便在完成脚本之前关闭连接。

Here's some simple code that works for me. 这里有一些适合我的简单代码。

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")

This is based on a previous answer . 这是基于之前的答案

if you have Kerberos installed and talking to AD, as would be the case with, say, Centrify Express installed and running, you might just use python-kerberos. 如果您安装了Kerberos并与AD通信,例如安装和运行Centrify Express的情况,您可能只使用python-kerberos。 Eg 例如

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

would return True a user 'joe' has password 'pizza' in the Kerberos realm X.PIZZA.COM. 将返回True用户'joe'在Kerberos领域X.PIZZA.COM中有密码'pizza'。 (typically, I think, the latter would be the same as the name of the AD Domain) (通常,我认为,后者与AD域的名称相同)

I see your comment to @Johan Buret about the DN not fixing your problem, but I also believe that is what you should look into. 我看到你对@Johan Buret的评论关于DN没有解决你的问题,但我也相信这是你应该研究的。

Given your example, the DN for the default administrator account in AD will be: cn=Administrator,cn=Users,dc=mydomain,dc=co,dc=uk - please try that. 举个例子,AD中默认管理员帐户的DN将是:cn = Administrator,cn = Users,dc = mydomain,dc = co,dc = uk - 请试试。

I had the same issue, but it was regarding the password encoding 我有同样的问题,但它是关于密码编码

.encode('iso-8859-1')

Solved the problem. 解决了这个问题。

I tried to add 我试着补充一下

l.set_option(ldap.OPT_REFERRALS, 0) l.set_option(ldap.OPT_REFERRALS,0)

but instead of an error Python just hangs and won't respond to anything any more. 但不是错误Python只是挂起而不再响应任何东西。 Maybe I'm building the search query wrong, what is the Base part of the search? 也许我正在构建错误的搜索查询,搜索的基本部分是什么? I'm using the same as the DN for the simple bind (oh, and I had to do l.simple_bind , instead of l.simple_bind_s ): 我使用与简单绑定相同的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)

I'm using AD LDS and the instance is registered for the current account. 我正在使用AD LDS,并且该实例已在当前帐户中注册。

Based on the excellent ldap3 tutorial : 基于优秀的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

I did the above in Python3 but it's supposed to be compatible with Python 2. 我在Python3中做了以上操作,但它应该与Python 2兼容。

Use a Distinguished Name to log on your system. 使用专有名称登录系统。 "CN=Your user,CN=Users,DC=b2t,DC=local" It should work on any LDAP system, including AD "CN=Your user,CN=Users,DC=b2t,DC=local"它应该适用于任何LDAP系统,包括AD

对我来说,从simple_bind_s()更改为bind()就可以了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM