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 myusername@mydomain.co.uk 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.


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.


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)

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.


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

Ini didasarkan pada jawaban sebelumnya .


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)


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.


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.


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.


1

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

.encode('iso-8859-1')

Memecahkan masalah.


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


0

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.