Pregunta

¿Cómo me autentico contra AD usando Python + LDAP? Actualmente estoy usando la biblioteca python-ldap y todo lo que produce son lágrimas.

Ni siquiera puedo vincularme para realizar una consulta simple:

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

Ejecutar esto con myusername@mydomain.co.uk contraseña nombre de usuario me da uno de dos errores:

Credenciales no válidas : cuando escribo mal o uso intencionalmente las credenciales incorrectas, no se puede autenticar.

  

ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, comentario: AcceptSecurityContext error, data 52e, vece', 'desc': 'Credenciales no válidas'}

O

  

ldap.OPERATIONS_ERROR: {'info': '00000000: LdapErr: DSID-0C090627, comentario: Para realizar esta operación, se debe completar un enlace exitoso en la conexión., datos 0, vece', 'desc': 'Error de operaciones'}

¿Qué me estoy perdiendo para enlazar correctamente?

Recibo los mismos errores en fedora y windows.

¿Fue útil?

Solución

me faltaba

l.set_option(ldap.OPT_REFERRALS, 0)

Desde el inicio.

Otros consejos

Si está abierto a usar pywin32, puede usar llamadas Win32 desde 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)

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

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("myuser@company.com", "mypassword")

Esto se basa en una respuesta anterior .

si tiene Kerberos instalado y hablando con AD, como sería el caso, por ejemplo, con Centrify Express instalado y en ejecución, puede usar python-kerberos. Por ejemplo,

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

devolvería Verdadero un usuario 'joe' tiene contraseña 'pizza' en el reino de Kerberos X.PIZZA.COM. (normalmente, creo, este último sería el mismo que el nombre del dominio AD)

Veo tu comentario a @Johan Buret acerca de que el DN no soluciona tu problema, pero también creo que eso es lo que debes considerar.

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

Traté de agregar

  

l.set_option (ldap.OPT_REFERRALS, 0)

pero en lugar de un error, Python simplemente se cuelga y ya no responde a nada. Tal vez estoy construyendo la consulta de búsqueda incorrectamente, ¿cuál es la parte base de la búsqueda? Estoy usando lo mismo que el DN para el enlace simple (oh, y tuve 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 está registrada para la cuenta actual.

Tuve el mismo problema, pero estaba relacionado con la codificación de contraseña

.encode('iso-8859-1')

Solucionó el problema.

Basado en el excelente 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

Hice lo anterior en Python3 pero se supone que es compatible con Python 2.

Use un nombre distinguido para iniciar sesión en su sistema. " CN = Su usuario, CN = Users, DC = b2t, DC = local " Debería funcionar en cualquier sistema LDAP, incluido AD

Para mí, cambiar de simple_bind_s () a bind () fue el truco.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top