Otentikasi terhadap direktori aktif menggunakan python + ldap

89

Bagaimana cara mengotentikasi AD menggunakan Python + LDAP. Saat ini saya menggunakan pustaka python-ldap dan yang dihasilkan hanyalah air mata.

Saya bahkan tidak bisa mengikat untuk melakukan kueri sederhana:

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

Menjalankan ini dengan [email protected] password usernamememberi saya salah satu dari dua kesalahan:

Invalid Credentials - Saat saya salah mengetik atau sengaja menggunakan kredensial yang salah, autentikasi gagal.

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

Atau

ldap.OPERATIONS_ERROR: {'info': '00000000: LdapErr: DSID-0C090627, komentar: Untuk melakukan operasi ini, pengikatan yang berhasil harus diselesaikan pada koneksi., data 0, vece', 'desc': 'Operations error '}

Apa yang saya lewatkan untuk mengikat dengan benar?

Saya mendapatkan kesalahan yang sama di fedora dan windows.

1729
sumber
2
"... dan yang dihasilkannya hanyalah air mata." Apakah air mata berima dengan Beruang atau Bir?
philshem

Jawaban:

47

aku menghilang

l.set_option(ldap.OPT_REFERRALS, 0)

Dari init.

1729
sumber
3
Akar penyebab bug ini adalah Anda memiliki rujukan di respons awal dan kode LDAP windows tidak mengirim kredensial ke server rujukan. Jika Anda menggunakan kredensial kerberos, seharusnya berfungsi.
schlenk
2
Saya memiliki gejala yang berbeda tetapi opsi yang sama ini memperbaiki masalah saya. Diringkas dalam posting blog: chaverma.com/blog/index.php/2013/06/…
Chris
Tidak yakin apakah terkait, tetapi saya memiliki masalah yang sama dan tampaknya solusi 1729 melakukan sesuatu - Tetapi terkadang server LDAP hanya menjawab KREDENSIAL TIDAK VALID dengan segera. Setelah beberapa saat itu menjadi tenang dan bekerja kembali.
Nitay
29

Jika Anda terbuka untuk menggunakan pywin32, Anda dapat menggunakan panggilan Win32 dari Python. Inilah yang kami lakukan di server web CherryPy kami:

import win32security
token = win32security.LogonUser(
    username,
    domain,
    password,
    win32security.LOGON32_LOGON_NETWORK,
    win32security.LOGON32_PROVIDER_DEFAULT)
authenticated = bool(token)
davidavr.dll
sumber
3
sederhana dan bersih! Terima kasih!
alexroat
Solusi ini bekerja untuk saya dalam aplikasi Python Flask saat berada di belakang proxy perusahaan NTLM yang terbatas. Beberapa opsi berbasis LDAP lainnya tidak akan berfungsi.
Gigaflop
7

Itu berhasil bagi saya, l.set_option (ldap.OPT_REFERRALS, 0) adalah kunci untuk mengakses ActiveDirectory. Selain itu, menurut saya Anda harus menambahkan "con.unbind ()" untuk menutup koneksi sebelum menyelesaikan skrip.

alfredocambera.dll
sumber
8
Dari dokumentasi python-ldap : Contoh dari LDAPObjectdikembalikan oleh initialize(). Sambungan secara otomatis tidak terikat dan ditutup saat objek LDAP dihapus.
Søren Løvborg
Anda menutup sesi, bukan koneksi.
Romulus
5

Berikut beberapa kode sederhana yang berhasil untuk saya.

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

Ini didasarkan pada jawaban sebelumnya .

JohnMudd
sumber
1
Ini tidak berfungsi lagi, Anda akan menerimaAttributeError: module 'ldap' has no attribute 'open'
Josh Correia
3

jika Anda memiliki Kerberos terinstal dan berbicara dengan AD, seperti halnya dengan, katakanlah, Centrify Express diinstal dan dijalankan, Anda mungkin hanya menggunakan python-kerberos. Misalnya

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

akan mengembalikan True pengguna 'joe' memiliki kata sandi 'pizza' di ranah Kerberos X.PIZZA.COM. (biasanya, menurut saya, nama yang terakhir sama dengan nama Domain AD)

Dima Pasechnik
sumber
2

Saya melihat komentar Anda untuk @Johan Buret tentang DN yang tidak memperbaiki masalah Anda, tetapi saya juga percaya bahwa itulah yang harus Anda perhatikan.

Diberikan contoh Anda, DN untuk akun administrator default di AD adalah: cn = Administrator, cn = Users, dc = mydomain, dc = co, dc = uk - silakan coba.

Daniel Bungert
sumber
2

Berdasarkan tutorial ldap3 yang sangat baik :

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

Saya melakukan hal di atas dengan Python3 tetapi seharusnya kompatibel dengan Python 2.

Nagev
sumber
1

Saya mencoba menambahkan

l.set_option (ldap.OPT_REFERRALS, 0)

tetapi alih-alih kesalahan, Python hanya hang dan tidak merespons apa pun lagi. Mungkin saya salah membuat kueri penelusuran, apa yang menjadi bagian Basis dari penelusuran? Saya menggunakan sama dengan DN untuk ikatan sederhana (oh, dan saya harus melakukan l.simple_bind, bukan 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)

Saya menggunakan AD LDS dan instance terdaftar untuk akun saat ini.

lanoxx.dll
sumber
1

Saya memiliki masalah yang sama, tetapi ini terkait dengan pengkodean kata sandi

.encode('iso-8859-1')

Memecahkan masalah.

Dr.Ü
sumber
0

Gunakan Nama yang Dibedakan untuk masuk ke sistem Anda. "CN=Your user,CN=Users,DC=b2t,DC=local" Ini harus bekerja pada sistem LDAP apa pun, termasuk AD

Johan Buret
sumber
0

Bagi saya, mengubah dari simple_bind_s()menjadi bind()berhasil.

xcl
sumber