web-dev-qa-db-fra.com

Authentification auprès d'Active Directory à l'aide de python + ldap

Comment puis-je m'authentifier auprès de AD à l'aide de Python + LDAP. J'utilise actuellement la bibliothèque python-ldap et elle ne produit que des larmes.

Je ne peux même pas me lier pour effectuer une requête 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()

Exécuter ceci avec [email protected] password username me donne l'une des deux erreurs suivantes:

Invalid Credentials - Lorsque je me trompe ou que j'utilise intentionnellement de mauvaises informations d'identification, l'authentification échoue.

ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, commentaire: erreur AcceptSecurityContext, données 52e, vece', 'desc': 'Informations d'identification non valides'}

Ou 

ldap.OPERATIONS_ERROR: {'info': '00000000: LdapErr: DSID-0C090627, commentaire: Pour effectuer cette opération, une liaison doit être effectuée avec succès sur la connexion., données 0, vece', 'desc': '' Erreur d'opération '}

Qu'est-ce qui me manque pour me lier correctement?

Je reçois les mêmes erreurs sur Fedora et Windows.

83
1729

Je manquais 

l.set_option(ldap.OPT_REFERRALS, 0)

De l'init.

44
1729

Si vous êtes prêt à utiliser pywin32, vous pouvez utiliser les appels Win32 à partir de Python. Voici ce que nous faisons sur notre serveur Web CherryPy:

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

Cela a fonctionné pour moi l.set_option (ldap.OPT_REFERRALS, 0) était la clé pour accéder à ActiveDirectory. De plus, je pense que vous devriez ajouter un "con.unbind ()" afin de fermer la connexion avant de terminer le script.

7
alfredocambera

Voici un code simple qui fonctionne pour moi.

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

Ceci est basé sur un réponse précédente .

4
JohnMudd

si Kerberos est installé et parle à AD, comme ce serait le cas avec Centrify Express installé et en cours d'exécution, vous pouvez simplement utiliser python-kerberos. Par exemple.

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

renverrait True un utilisateur "joe" a le mot de passe "pizza" dans le domaine Kerberos X.PIZZA.COM . (généralement, ce dernier est identique au nom du domaine AD)

3
Dima Pasechnik

Je vois votre commentaire à @Johan Buret sur le fait que le nom distinctif ne résout pas votre problème, mais je crois aussi que c'est ce que vous devriez examiner.

Dans votre exemple, le nom distinctif du compte administrateur par défaut dans AD est le suivant:.

2
Daniel Bungert

J'ai essayé d'ajouter

l.set_option (ldap.OPT_REFERRALS, 0)

mais au lieu d’une erreur, Python se bloque et ne répond plus à rien. Peut-être que je construis mal la requête de recherche, quelle est la partie base de la recherche? J'utilise le même nom que le DN pour la liaison simple (oh, et je devais faire l.simple_bind au lieu 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)

J'utilise AD LDS et l'instance est enregistrée pour le compte actuel.

1
lanoxx

J'ai eu le même problème, mais c'était en ce qui concerne le codage du mot de passe

.encode('iso-8859-1')

Résolu le problème.

1
Dr.Ü

Pour moi, passer de simple_bind_s() à bind() a été efficace.

0
xcl

Utilisez un nom distinctif pour vous connecter à votre système."CN=Your user,CN=Users,DC=b2t,DC=local"Il devrait fonctionner sur tout système LDAP, y compris AD

0
Johan Buret

Basé sur l'excellent tutoriel 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

J'ai fait ce qui précède en Python3 mais c'est supposé être compatible avec Python 2.

0
Nagev