Belajar LDAP - Web Application Integration
Series/Belajar LDAP/Episode 21
Episode 21 of 31

Belajar LDAP - Web Application Integration

Membahas cara mengintegrasikan aplikasi web dengan LDAP: autentikasi lewat PHP, Python, Java, Node.js, dan Go, perlindungan di level Apache dan Nginx, framework aplikasi, pola SSO dengan CAS, SAML, dan Keycloak, serta praktik terbaik untuk koneksi dan kredensial aplikasi.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Pendahuluan

Pada episode 20, LDAP melayani email dan address book. Episode 21 ini memakai directory yang sama untuk aplikasi web: autentikasi user di aplikasi yang ditulis dengan PHP, Python, Java, Node.js, dan Go; perlindungan akses di level web server; dukungan framework populer; hingga pola SSO yang lebih besar seperti CAS, SAML, OAuth2, dan Keycloak. Pola bind DN, base DN, dan filter yang kalian kuasai di episode sebelumnya akan dipakai terus di sini — hanya dengan pembungkus bahasa yang berbeda.

Pola Dasar Autentikasi Aplikasi

Semua integrasi LDAP dari aplikasi mengikuti pola yang sama: aplikasi melakukan bind dengan DN user yang mencoba login, dan jika bind berhasil, user terautentikasi. Langkah detailnya hampir selalu berupa:

  1. Aplikasi mencari DN user berdasarkan username lewat search (biasanya filter pada atribut uid).
  2. Aplikasi melakukan bind ke DN tersebut dengan password yang diketik user.
  3. Jika bind berhasil, aplikasi mengambil atribut tambahan user dari directory.
  4. Aplikasi membangun sesi dan otorisasi berdasarkan group atau atribut.

Pola ini disebut bind as user. Alternatifnya adalah bind as service: aplikasi memakai akun khusus untuk melakukan search dan memvalidasi password dengan membaca atribut hash — pola ini kurang disarankan karena memaksa aplikasi membaca password hash, padahal aturan directory modern menyimpan hash di luar jangkauan aplikasi.

Autentikasi LDAP Berdasarkan Bahasa

Setiap ekosistem bahasa punya cara khas untuk berbicara dengan LDAP, tetapi semuanya mengimplementasikan pola dasar di atas.

PHP dengan LDAP Extension

PHP memiliki ekstensi ldap bawaan. Contoh autentikasi sederhana:

Autentikasi LDAP di PHP
<?php
$ldap = ldap_connect("ldap.example.com");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
$result = ldap_search($ldap, "ou=people,dc=example,dc=com",
    "(uid=" . ldap_escape($username) . ")");
$entries = ldap_entries($result);
$dn = $entries[0]["dn"];
$auth = @ldap_bind($ldap, $dn, $password);

Perhatikan ldap_escape — selalu sanitasi input username sebelum disisipkan ke filter untuk mencegah LDAP injection. Kesalahan klasik pemula adalah menyambung string filter langsung dari input user, yang membuka celah manipulasi filter.

Python dengan ldap3 dan python-ldap

Python punya dua library utama: python-ldap (bind ke libldap C) dan ldap3 (implementasi murni Python). ldap3 lebih mudah dipakai karena API-nya sederhana:

Autentikasi LDAP di Python
from ldap3 import Server, Connection, ALL
 
server = Server("ldap.example.com", get_info=ALL)
conn = Connection(server, "uid=budi,ou=people,dc=example,dc=com",
                  "password", auto_bind=True)

auto_bind=True langsung melakukan bind saat koneksi dibuat. Jika bind gagal, exception dilempar dan aplikasi bisa menampilkan pesan login gagal. ldap3 juga menyediakan API yang bersih untuk search dan manipulasi entry.

Java dengan JNDI

Java memakai JNDI (Java Naming and Directory Interface) untuk mengakses LDAP. Pola bind user di Java melibatkan pembuatan konteks awal dengan environment properties:

Bind LDAP dengan JNDI
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
    "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://ldap.example.com");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "uid=budi,ou=people,dc=example,dc=com");
env.put(Context.SECURITY_CREDENTIALS, "password");
DirContext ctx = new InitialDirContext(env);

JNDI adalah fondasi dari banyak framework Java seperti Spring Security LDAP. Jika konstruksi InitialDirContext berhasil, autentikasi berhasil; exception AuthenticationException menandakan kredensial salah.

Node.js dan Go

Di Node.js, library seperti ldapjs menyediakan klien LDAP dengan API berbasis event dan promise. Di Go, library seperti go-ldap adalah standar yang paling banyak dipakai. Keduanya mengimplementasikan bind, search, dan modify dengan cara yang idiomatis untuk ekosistem masing-masing. Semua pilihan bahasa di atas tetap memakai protokol LDAP yang sama — perbedaannya hanya di ergonomi API.

Web Server Authentication

Kadang autentikasi tidak perlu ada di aplikasi — web server bisa melakukannya lebih dulu. Pendekatan ini melindungi seluruh aplikasi tanpa mengubah satu baris pun kode aplikasi.

Apache dengan mod_authnz_ldap

Apache punya modul mod_authnz_ldap untuk autentikasi dan otorisasi berbasis LDAP:

Linuxmod_authnz_ldap di Apache
AuthType Basic
AuthName "Area Terproteksi"
AuthBasicProvider ldap
AuthLDAPURL "ldap://ldap.example.com/ou=people,dc=example,dc=com?uid"
AuthLDAPBindDN "cn=apache,ou=system,dc=example,dc=com"
AuthLDAPBindPassword secret
Require valid-user

AuthLDAPURL menentukan server, base, dan atribut yang dipakai untuk mencari user. Require valid-user berarti semua user yang valid di LDAP boleh masuk; untuk membatasi group, ganti dengan Require ldap-group cn=staff,ou=groups,dc=example,dc=com.

Nginx dengan ldap-auth

Nginx tidak punya modul LDAP bawaan, tetapi bisa bekerja sama dengan daemon nginx-ldap-auth (umumnya berbasis nginx-ldap-auth-ng). Nginx meneruskan permintaan ke daemon auth lewat subrequest; jika daemon memvalidasi kredensial ke LDAP, akses diteruskan ke aplikasi. Pola ini memberikan Basic Authentication LDAP dengan kinerja Nginx yang tinggi.

PendekatanKelebihanKekurangan
Auth di aplikasiKontrol penuh, fitur kayaHarus diimplementasikan per aplikasi
Auth di web serverTerpusat, tanpa ubah aplikasiTerbatas pada Basic Auth
SSO (Keycloak dll.)Satu login banyak aplikasiInfrastruktur tambahan

Framework Aplikasi

Sebagian besar framework populer memiliki plugin LDAP yang siap pakai:

  • Djangodjango-auth-ldap menyediakan backend autentikasi yang bisa dipasang di settings, lengkap dengan mapping group ke permission.
  • Spring Securityspring-security-ldap menawarkan integration dengan JNDI dan support untuk bind dan otorisasi berbasis group.
  • Ruby on Rails — gem net-ldap ditambah pola authentication di model memberi autentikasi LDAP sederhana.
  • Laravel — library seperti laravel-ldap membungkus operasi LDAP ke dalam sistem auth Laravel yang sudah ada.

Memakai plugin framework lebih aman daripada menulis dari nol: error handling, caching, dan mapping group sudah matang dan teruji.

SSO Integration dengan LDAP Backend

Di skala enterprise, aplikasi jarang berautentikasi langsung ke LDAP. Sebagai gantinya, LDAP menjadi backend identity dari server SSO, dan aplikasi berautentikasi ke server SSO tersebut.

TeknologiPeranHubungan dengan LDAP
CAS (Central Authentication Service)Server login terpusatMelakukan bind ke LDAP
SAMLStandar federasi identitasIdP membaca user dari LDAP
OAuth2/OIDCStandar delegasi aksesProvider memvalidasi lewat LDAP
KeycloakPlatform IAM modernUser federation ke LDAP

Keycloak adalah contoh paling populer: kalian menambah User Federation LDAP, menghubungkan ke server OpenLDAP, dan semua user LDAP langsung tersedia untuk login di Keycloak. Aplikasi kemudian memakai protokol OIDC atau SAML ke Keycloak, bukan ke LDAP secara langsung. Ini memisahkan autentikasi dari aplikasi dan memberi satu titik untuk MFA dan policy.

Best Practices

Integrasi LDAP yang rapuh dibangun dari disiplin operasional, bukan hanya kode yang benar:

  • Connection pooling — jangan buka koneksi LDAP per request; pakai pool yang di-share antar request.
  • Bind DN khusus per aplikasi — setiap aplikasi memakai akun sistem sendiri, sehingga audit dan revoke lebih mudah.
  • Read-only access — akun aplikasi sebaiknya hanya bisa membaca atribut yang dibutuhkan.
  • Secure credential storage — password akun aplikasi disimpan di secret manager atau environment, bukan hardcoded.
  • Caching user data — data LDAP jarang berubah; cache di aplikasi mengurangi beban directory.
  • Timeouts dan retry — beri batas waktu bind dan search agar aplikasi tidak menggantung saat server LDAP lambat.

Important

Filter yang menerima input user tanpa sanitasi adalah celah LDAP injection — serupa dengan SQL injection. Selalu escape nilai yang disisipkan ke filter, atau gunakan escape function yang disediakan library seperti ldap_escape di PHP dan escape_filter_chars di ldap3. Kredibilitas satu filter yang bisa dimanipulasi cukup untuk menghancurkan seluruh directory.

Penutup

Pada episode 21 ini, kalian menghubungkan aplikasi web ke LDAP: pola dasar bind as user, autentikasi di PHP, Python, Java, Node.js, dan Go, perlindungan di level Apache dan Nginx, dukungan framework seperti Django dan Spring, integrasi SSO dengan CAS, SAML, dan Keycloak, serta praktik terbaik untuk koneksi pooling dan keamanan kredensial.

Inti yang harus dibawa pulang:

  • Bind as user adalah pola universal — semua bahasa mengimplementasikannya dengan cara yang sama.
  • Sanitasi filter wajib untuk mencegah LDAP injection.
  • Web server auth dan SSO mengurangi pengulangan autentikasi di tiap aplikasi.
  • Akun aplikasi dipisah dan read-only agar audit dan revoke mudah.

Di episode 22 berikutnya, kalian melebarkan penglihatan ke ekosistem Microsoft: Active Directory dan LDAP — bagaimana AD DS memakai LDAP sebagai protokol intinya, perbedaan schema dan atribut dengan OpenLDAP, serta cara Linux bergabung dengan domain AD. Pola bind dan filter yang kalian kuasai di episode ini tetap berlaku di sana.