2008-09-26 32 views
77

¿Cómo me autentico contra AD usando Python + LDAP? Actualmente estoy usando la biblioteca python-ldap y todo lo que está produciendo es lágrimas.Autenticación contra el directorio activo usando python + ldap

Ni siquiera puedo obligar a realizar una consulta sencilla:

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

La ejecución de este con [email protected] password username me da uno de dos errores:

Invalid Credentials - Cuando ha tecleado mal intencionada o utilizar credenciales incorrectas falla para autenticarse

ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 52e, vece', 'desc': 'Invalid credentials'}

O

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'}

¿Cuál falto a cabo para unir correctamente?

Recibo los mismos errores en fedora y windows.

+1

"... y todo lo que produce son lágrimas". ¿** lágrimas ** rima con osos o cervezas? – philshem

Respuesta

43

me estaba perdiendo

l.set_option(ldap.OPT_REFERRALS, 0) 

Desde el init.

+1

No puedo decir si esto resolvió su problema. –

+2

Tuve el mismo problema, y ​​lo resolvió para mí. – Staale

+3

La causa principal de este error es que tiene referencias en la respuesta inicial y el código LDAP de Windows no envía las credenciales al servidor de referencia. Si usó las credenciales de Kerberos debería funcionar. – schlenk

1

Utilice un nombre completo para iniciar sesión en su sistema. "CN=Your user,CN=Users,DC=b2t,DC=local" Debería funcionar en cualquier sistema LDAP, incluidos AD

+0

No, no fue eso. – 1729

23

Si está abierto a usar pywin32, puede usar las llamadas Win32 de Python. Esto es lo que hacemos en nuestro servidor web CherryPy:

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

simple y limpio! ¡Gracias! – alexroat

2

veo tu comentario a @Johan Buret sobre el DN no arreglar su problema, pero también creo que es lo que debemos analizar.

Dado su ejemplo, el DN para la cuenta de administrador predeterminada en AD será: cn = Administrador, cn = Usuarios, dc = mydomain, dc = co, dc = uk - por favor intente eso.

7

Eso funcionó para mí, l.set_option (ldap.OPT_REFERRALS, 0) fue la clave para acceder a ActiveDirectory. Además, creo que debe agregar un "con.unbind()" para cerrar la conexión antes de finalizar el script.

+7

De la [documentación de python-ldap] (http://www.python-ldap.org/doc/html/ldap.html): Las instancias de 'LDAPObject' son devueltas por' initialize() '. La conexión se desconecta automáticamente y se cierra cuando se elimina el objeto LDAP. –

+0

Cierre la sesión, no la conexión. – Romulus

0

Si esto es parte de una aplicación web destinada a usuarios de anuncios autenticados, this so question podría ser de su interés.

1

He intentado añadir

l.set_option(ldap.OPT_REFERRALS, 0)

pero en lugar de un error de Python sólo se bloquea y no responde a nada más. Tal vez estoy construyendo la consulta de búsqueda equivocada, ¿cuál es la parte básica de la búsqueda? Estoy usando el mismo que el DN para el enlace simple (ah, y que tenía que hacer l.simple_bind, en lugar de 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) 

estoy usando AD LDS y la instancia se ha registrado para la cuenta corriente .

3

si tiene instalado Kerberos y habla con AD, como sería el caso de, digamos, Centrify Express instalado y en ejecución, podría usar python-kerberos.P.ej.

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

volvería Verdadero un 'Joe' usuario tiene la contraseña 'pizza' en el X.PIZZA.COM dominio de Kerberos. (por lo general, en mi opinión, éste sería el mismo que el nombre del dominio AD)

0

Para mí el cambio de simple_bind_s() a bind() hizo el truco.

3

Aquí hay un código simple que funciona para mí.

import ldap # run 'pip install python-ldap' to install ldap module. 
conn = ldap.open("ldaphost.company.com") 
conn.simple_bind_s("[email protected]", "mypassword") 

Esto se basa en un previous answer.

1

que tenían el mismo problema, pero era con respecto a la codificación de contraseña

.encode('iso-8859-1') 

solucionado el problema.

Cuestiones relacionadas