Python + ldap kullanarak aktif dizine karşı kimlik doğrulama


89

Python + LDAP kullanarak AD'ye karşı nasıl kimlik doğrulaması yaparım. Şu anda python-ldap kitaplığını kullanıyorum ve onun ürettiği tek şey gözyaşları.

Basit bir sorgu gerçekleştirmek için bile bağlanamıyorum:

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

Bunu çalıştırmak myusername@mydomain.co.uk password usernamebana iki hatadan birini veriyor:

Invalid Credentials - Yanlış yazdığımda veya kasıtlı olarak yanlış kimlik bilgileri kullandığımda kimlik doğrulaması başarısız oluyor.

ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, yorum: AcceptSecurityContext hatası, data 52e, vece', 'desc': 'Geçersiz kimlik bilgileri'}

Veya

ldap.OPERATIONS_ERROR: {'info': '00000000: LdapErr: DSID-0C090627, yorum: Bu işlemi gerçekleştirmek için bağlantıda başarılı bir bağlama tamamlanmalıdır., data 0, vece', 'desc': 'İşlemler hatası '}

Düzgün bağlamam için neyi kaçırıyorum?

Fedora ve pencerelerde aynı hataları alıyorum.


2
"... ve ürettiği tek şey gözyaşları." Does gözyaşları Bears veya Beers ile kafiyeli?
philshem

Yanıtlar:


48

Özlüyordum

l.set_option(ldap.OPT_REFERRALS, 0)

Başlangıçtan.


3
Bu hatanın temel nedeni, ilk yanıtta yönlendirmelerinizin olması ve Windows LDAP kodunun kimlik bilgilerini başvuru sunucusuna göndermemesidir. Kerberos kimlik bilgilerini kullandıysanız, çalışmalıdır.
schlenk

2
Farklı semptomlarım vardı ama bu aynı seçenek sorunumu çözdü. Bunu bir blog gönderisinde özetledi: chaverma.com/blog/index.php/2013/06/…
Chris

İlişkili olup olmadığından emin değilim, ama aynı sorunu yaşadım ve 1729'un çözümü bir şey yaptı gibi görünüyor - Ama bazen LDAP sunucusu sadece GEÇERSİZ KİMLİKLERİ hemen yanıtlıyor. Bir süre sonra sakinleşir ve tekrar çalışır.
Nitay

29

Pywin32'yi kullanmaya açıksanız, Python'dan Win32 çağrılarını kullanabilirsiniz. CherryPy web sunucumuzda yaptığımız şey şu:

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

3
Basit ve temiz! Teşekkürler!
alexroat

Bu çözüm, kısıtlayıcı bir NTLM kurumsal proxy'nin arkasında iken bir Python Flask uygulamasında benim için çalıştı. Diğer bazı LDAP tabanlı seçenekler işe yaramaz.
Gigaflop

7

Bu benim için çalıştı, l.set_option (ldap.OPT_REFERRALS, 0) ActiveDirectory'ye erişimin anahtarı oldu. Ayrıca betiği bitirmeden önce bağlantıyı kapatmak için bir "con.unbind ()" eklemeniz gerektiğini düşünüyorum.


8
Gönderen piton-ldap belgelerine : Örneklerini ait LDAPObjecttarafından döndürülen initialize(). LDAP nesnesi silindiğinde bağlantı otomatik olarak kesilir ve kapatılır.
Søren Løvborg

Bağlantıyı değil oturumu kapatırsınız.
Romulus

5

İşte benim için çalışan bazı basit kodlar.

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

Bu, önceki bir cevaba dayanmaktadır .


1
Bu artık çalışmıyor, alacaksınızAttributeError: module 'ldap' has no attribute 'open'
Josh Correia

3

Eğer Kerberos'u kurduysanız ve AD ile konuştuysanız, örneğin Centrify Express'in kurulu ve çalışmasında olduğu gibi, sadece python-kerberos kullanabilirsiniz. Örneğin

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

True döndürür Bir kullanıcı 'joe' Kerberos bölgesi X.PIZZA.COM'da 'pizza' şifresine sahip. (tipik olarak, ikincisinin AD Alanının adıyla aynı olacağını düşünüyorum)


2

@Johan Buret'e DN sorununuzu çözmeyen yorumunuzu görüyorum, ama aynı zamanda bakmanız gereken şeyin bu olduğuna inanıyorum.

Örneğinize göre, AD'deki varsayılan yönetici hesabının DN'si şöyle olacaktır: cn = Yönetici, cn = Kullanıcılar, dc = alanadım, dc = co, dc = uk - lütfen bunu deneyin.


2

Mükemmel LDAP3 eğitimine göre :

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

Yukarıdakileri Python3'te yaptım ama Python 2 ile uyumlu olması gerekiyordu.


1

Eklemeye çalıştım

l.set_option (ldap.OPT_REFERRALS, 0)

ancak Python bir hata yerine kilitleniyor ve artık hiçbir şeye yanıt vermiyor. Belki arama sorgusunu yanlış oluşturuyorum, aramanın Temel kısmı nedir? Basit bağlama için DN ile aynı şeyi kullanıyorum (oh l.simple_bind, bunun yerine yapmak zorundaydım 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)

AD LDS kullanıyorum ve örnek cari hesap için kayıtlı.


1

Aynı sorunu yaşadım, ancak şifre kodlamasıyla ilgiliydi

.encode('iso-8859-1')

Sorunu çözdüm.


0

Sisteminizde oturum açmak için Ayırt Edici bir Ad kullanın. "CN=Your user,CN=Users,DC=b2t,DC=local" AD dahil olmak üzere herhangi bir LDAP sisteminde çalışmalıdır


0

Benim simple_bind_s()için bind()yerine geçmek hile yaptı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.