Authentifizierung gegen Active Directory mit Python + LDAP


89

Wie authentifiziere ich mich mit Python + LDAP gegen AD? Ich benutze derzeit die Python-LDAP-Bibliothek und alles, was sie produziert, sind Tränen.

Ich kann nicht einmal binden, um eine einfache Abfrage durchzuführen:

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

Wenn myusername@mydomain.co.uk password usernameich dies mit ausführe, habe ich einen von zwei Fehlern:

Invalid Credentials - Wenn ich falsch schreibe oder absichtlich falsche Anmeldeinformationen verwende, kann die Authentifizierung nicht durchgeführt werden.

ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, Kommentar: AcceptSecurityContext-Fehler, Daten 52e, vece', 'desc': 'Ungültige Anmeldeinformationen'}

Oder

ldap.OPERATIONS_ERROR: {'info': '00000000: LdapErr: DSID-0C090627, Kommentar: Um diesen Vorgang auszuführen, muss eine erfolgreiche Bindung für die Verbindung abgeschlossen werden., Daten 0, vece', 'desc': 'Operations error '}

Was verpasse ich, um richtig zu binden?

Ich erhalte die gleichen Fehler auf Fedora und Windows.


2
"... und alles was es produziert sind Tränen." Hat Tränen Reim mit Bären oder Bier?
Philshem

Antworten:


47

ich habe gefehlt

l.set_option(ldap.OPT_REFERRALS, 0)

Von der Init.


3
Die Hauptursache für diesen Fehler ist, dass Sie in der ersten Antwort Verweise haben und der Windows-LDAP-Code die Anmeldeinformationen nicht an den Verweisserver sendet. Wenn Sie Kerberos-Anmeldeinformationen verwendet haben, sollte dies funktionieren.
Schlenk

2
Ich hatte verschiedene Symptome, aber dieselbe Option hat mein Problem behoben. Fasst es in einem Blog-Beitrag zusammen: chaverma.com/blog/index.php/2013/06/…
Chris

Ich bin mir nicht sicher, ob ich verwandt bin, aber ich hatte das gleiche Problem und es scheint, dass die Lösung von 1729 etwas bewirkt hat - aber manchmal antwortet der LDAP-Server einfach sofort auf UNGÜLTIGE KREDENTIALIEN. Nach einer Weile beruhigt es sich und funktioniert wieder.
Nitay

28

Wenn Sie für die Verwendung von pywin32 offen sind, können Sie Win32-Aufrufe von Python verwenden. Dies tun wir auf unserem CherryPy-Webserver:

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

3
einfach und sauber! Vielen Dank!
Alexroat

Diese Lösung funktionierte für mich in einer Python Flask-Anwendung hinter einem restriktiven NTLM-Unternehmensproxy. Einige andere LDAP-basierte Optionen würden einfach nicht funktionieren.
Gigaflop

7

Das hat bei mir funktioniert. L.set_option (ldap.OPT_REFERRALS, 0) war der Schlüssel für den Zugriff auf das ActiveDirectory. Darüber hinaus denke ich, dass Sie ein "con.unbind ()" hinzufügen sollten, um die Verbindung zu schließen, bevor Sie das Skript beenden.


8
Aus der Python-LDAP-Dokumentation : Instanzen von LDAPObjectwerden von zurückgegeben initialize(). Die Verbindung wird automatisch gelöst und geschlossen, wenn das LDAP-Objekt gelöscht wird.
Søren Løvborg

Sie schließen die Sitzung, nicht die Verbindung.
Romulus

5

Hier ist ein einfacher Code, der für mich funktioniert.

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

Dies basiert auf einer vorherigen Antwort .


Dies funktioniert nicht mehr, Sie erhaltenAttributeError: module 'ldap' has no attribute 'open'
Josh Correia

3

Wenn Sie Kerberos installiert haben und mit AD sprechen, wie dies beispielsweise bei Centrify Express der Fall ist und ausgeführt wird, verwenden Sie möglicherweise nur Python-Kerberos. Z.B

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

würde True zurückgeben. Ein Benutzer 'joe' hat das Passwort 'pizza' im Kerberos-Bereich X.PIZZA.COM. (Ich denke, letzteres entspricht normalerweise dem Namen der AD-Domäne.)


2

Ich sehe Ihren Kommentar an @Johan Buret über den DN, der Ihr Problem nicht behebt, aber ich glaube auch, dass Sie sich darum kümmern sollten.

In Ihrem Beispiel lautet der DN für das Standardadministratorkonto in AD: cn = Administrator, cn = Benutzer, dc = meine Domäne, dc = co, dc = uk - versuchen Sie das bitte.


2

Basierend auf dem hervorragenden 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

Ich habe das oben genannte in Python3 gemacht, aber es soll mit Python 2 kompatibel sein.


1

Ich habe versucht hinzuzufügen

l.set_option (ldap.OPT_REFERRALS, 0)

aber statt eines Fehlers hängt Python einfach und reagiert auf nichts mehr. Vielleicht baue ich die Suchabfrage falsch. Was ist der Basisteil der Suche? Ich verwende das gleiche wie der DN für die einfache Bindung (oh, und ich musste l.simple_bindstattdessen tun 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)

Ich verwende AD LDS und die Instanz ist für das aktuelle Konto registriert.


1

Ich hatte das gleiche Problem, aber es ging um die Passwortkodierung

.encode('iso-8859-1')

Problem gelöst.


0

Verwenden Sie einen eindeutigen Namen, um sich bei Ihrem System anzumelden. "CN=Your user,CN=Users,DC=b2t,DC=local" Es sollte auf jedem LDAP-System einschließlich AD funktionieren


0

Für mich hat der Wechsel von simple_bind_s()zu bind()den Trick gemacht.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.