Mengautentikasi dalam PHP menggunakan LDAP melalui Active Directory

104

Saya mencari cara untuk mengotentikasi pengguna melalui LDAP dengan PHP (dengan Active Directory sebagai penyedia). Idealnya, ini harus dapat berjalan di IIS 7 ( adLDAP melakukannya di Apache). Adakah yang pernah melakukan hal serupa, dengan sukses?

  • Sunting: Saya lebih suka perpustakaan / kelas dengan kode yang siap digunakan ... Akan konyol untuk menciptakan roda ketika seseorang telah melakukannya.
DV.
sumber
Saya pikir drupal memiliki modul untuk thatr
redben

Jawaban:

167

Mengimpor seluruh pustaka tampaknya tidak efisien ketika yang Anda butuhkan pada dasarnya hanyalah dua baris kode ...

$ldap = ldap_connect("ldap.example.com");
if ($bind = ldap_bind($ldap, $_POST['username'], $_POST['password'])) {
  // log them in!
} else {
  // error message
}
ceejayoz
sumber
43
Beberapa instalasi AD akan berhasil diikat jika kata sandi yang diberikan kosong. Hati-hati dengan ini! Anda mungkin perlu memastikan sandi tidak kosong sebelum mencoba mengautentikasi.
diolemo
@diolemo Adakah cara untuk mencegah hal ini tanpa memeriksa apakah sandi kosong?
Naftali aka Neal
@Neal Anda mungkin dapat menggunakannya ldap_set_optionuntuk membuatnya berperilaku dengan cara yang berbeda. Mungkin menyetel versi protokol? Anda harus bereksperimen. Saya pribadi menyarankan Anda untuk memeriksa kata sandi kosong, hanya untuk amannya.
diolemo
Untuk editor anonim: tidak, sepengetahuan saya, sanitasi input tidak diperlukan di sini karena ldap_bindakan menanganinya dan karakter khusus tidak menjadi masalah.
ceejayoz
14

Anda akan berpikir bahwa mengautentikasi pengguna di Active Directory akan menjadi proses yang cukup sederhana menggunakan LDAP di PHP tanpa memerlukan perpustakaan. Tetapi ada banyak hal yang dapat memperumitnya dengan cukup cepat:

  • Anda harus memvalidasi masukan. Nama pengguna / kata sandi kosong akan lolos sebaliknya.
  • Anda harus memastikan nama pengguna / kata sandi dikodekan dengan benar saat mengikat.
  • Anda harus mengenkripsi koneksi menggunakan TLS.
  • Menggunakan server LDAP terpisah untuk redundansi jika ada yang tidak berfungsi.
  • Mendapatkan pesan kesalahan informatif jika otentikasi gagal.

Sebenarnya lebih mudah dalam banyak kasus untuk menggunakan pustaka LDAP yang mendukung hal di atas. Saya akhirnya akhirnya menggulung perpustakaan saya sendiri yang menangani semua poin di atas: LdapTools (Yah, tidak hanya untuk otentikasi, itu dapat melakukan lebih banyak lagi). Ini dapat digunakan seperti berikut:

use LdapTools\Configuration;
use LdapTools\DomainConfiguration;
use LdapTools\LdapManager;

$domain = (new DomainConfiguration('example.com'))
    ->setUsername('username') # A separate AD service account used by your app
    ->setPassword('password')
    ->setServers(['dc1', 'dc2', 'dc3'])
    ->setUseTls(true);
$config = new Configuration($domain);
$ldap = new LdapManager($config);

if (!$ldap->authenticate($username, $password, $message)) {
    echo "Error: $message";
} else {
    // Do something...
}

Panggilan otentikasi di atas akan:

  • Validasi bahwa baik nama pengguna atau kata sandi tidak kosong.
  • Pastikan nama pengguna / kata sandi dikodekan dengan benar (UTF-8 secara default)
  • Coba server LDAP alternatif jika salah satu sedang down.
  • Enkripsi permintaan otentikasi menggunakan TLS.
  • Berikan informasi tambahan jika gagal (mis. Akun terkunci / dinonaktifkan, dll)

Ada perpustakaan lain untuk melakukan ini juga (seperti Adldap2). Namun, saya merasa cukup terdorong untuk memberikan beberapa informasi tambahan karena jawaban yang paling banyak dipilih sebenarnya adalah risiko keamanan yang dapat diandalkan tanpa validasi input yang dilakukan dan tidak menggunakan TLS.

ChadSikorra
sumber
1
Untuk koneksi LDAP, TLS sudah tidak digunakan lagi dan mendukung StartTLS: openldap.org/faq/data/cache/605.html .
zenlord
2
@zenlord Menggunakan ldaps://format untuk koneksi sudah tidak digunakan lagi. Dalam contoh saya, ketika Anda menetapkannya setUseTls(true)menggunakan ldap://format dan kemudian mengeluarkan StartTLS menggunakan ldap_start_tls($connection). Jadi TLS sendiri tidak usang, hanya menghubungkan menggunakan ldaps://(yang sebenarnya terhubung ke LDAP melalui port yang sama sekali berbeda).
ChadSikorra
12

Saya melakukan ini hanya dengan meneruskan kredensial pengguna ke ldap_bind ().

http://php.net/manual/en/function.ldap-bind.php

Jika akun dapat terikat ke LDAP, itu valid; jika tidak bisa, tidak. Jika semua yang Anda lakukan adalah otentikasi (bukan manajemen akun), saya tidak melihat kebutuhan akan perpustakaan.

Scott Reynen
sumber
9

Saya suka Kelas Zend_Ldap , Anda hanya dapat menggunakan kelas ini dalam proyek Anda, tanpa Zend Framework.

CMS
sumber
1
Saya mengalami kesulitan dalam menerapkan hal di atas untuk menemukan bahwa itu untuk mengelola bukan mengautentikasi. Saya bermaksud untuk beralih ke zend.auth.adapter.ldap
vdidxho