Domanda

Come posso autenticarmi con AD usando Python + LDAP. Attualmente sto usando la libreria python-ldap e tutto ciò che sta producendo sono lacrime.

Non riesco nemmeno a impegnarmi per eseguire una semplice 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()

L'esecuzione con myusername@mydomain.co.uk password username mi dà uno dei due errori:

Credenziali non valide - Quando digito male o uso intenzionalmente credenziali errate, l'autenticazione non riesce.

  

ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, commento: AcceptSecurityContext errore, dati 52e, vece', 'desc': 'Credenziali non valide'}

O

  

ldap.OPERATIONS_ERROR: {'info': '00000000: LdapErr: DSID-0C090627, commento: per eseguire questa operazione è necessario completare un collegamento riuscito sulla connessione., dati 0, vece', 'desc': "Errore operativo"}

Cosa mi sto perdendo per legare correttamente?

Ricevo gli stessi errori su fedora e windows.

È stato utile?

Soluzione

Mi mancava

l.set_option(ldap.OPT_REFERRALS, 0)

Dall'iniz.

Altri suggerimenti

Se sei aperto all'utilizzo di pywin32, puoi usare le chiamate Win32 da Python. Questo è ciò che facciamo nel nostro server Web CherryPy:

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

Ha funzionato per me, l.set_option (ldap.OPT_REFERRALS, 0) è stata la chiave per accedere ad ActiveDirectory. Inoltre, penso che dovresti aggiungere un " con.unbind () " per chiudere la connessione prima di terminare lo script.

Ecco un semplice codice che funziona per 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")

Questo si basa su una risposta precedente .

se hai Kerberos installato e stai parlando con AD, come nel caso, diciamo, di Centrify Express installato e in esecuzione, potresti semplicemente usare python-kerberos. Per es.

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

restituisce True un utente 'joe' ha la password 'pizza' nel regno di Kerberos X.PIZZA.COM. (in genere, penso, quest'ultimo sarebbe uguale al nome del dominio AD)

Vedo il tuo commento a @Johan Buret sul DN che non risolve il tuo problema, ma credo anche che sia quello che dovresti esaminare.

Dato il tuo esempio, il DN per l'account amministratore predefinito in AD sarà: cn = Amministratore, cn = Users, dc = mydomain, dc = co, dc = uk - per favore, prova.

Ho provato ad aggiungere

  

l.set_option (ldap.OPT_REFERRALS, 0)

ma invece di un errore Python si blocca e non risponde più a nulla. Forse sto costruendo la query di ricerca sbagliata, qual è la parte Base della ricerca? Sto usando lo stesso DN per il bind semplice (oh, e ho dovuto fare l.simple_bind , invece di 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)

Sto utilizzando AD LDS e l'istanza è registrata per l'account corrente.

Ho avuto lo stesso problema, ma riguardava la codifica della password

.encode('iso-8859-1')

Risolto il problema.

Basato sull'eccellente tutorial su 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

Ho fatto quanto sopra in Python3 ma dovrebbe essere compatibile con Python 2.

Usa un nome distinto per accedere al tuo sistema. " CN = Il tuo utente, CN = Users, DC = b2t, DC = local " Dovrebbe funzionare su qualsiasi sistema LDAP, incluso AD

Per me il passaggio da simple_bind_s () a bind () ha funzionato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top