Permudahkan akses direktori dengan Spring LDAP

Spring LDAP adalah kerangka kerja Spring yang mempermudah pengaturcaraan LDAP di platform Java. Dalam panduan langkah demi langkah ini untuk menggunakan Spring LDAP, anda akan mempelajari bagaimana kerangka kerja menangani pengekodan tahap rendah yang diperlukan oleh kebanyakan pelanggan LDAP, sehingga anda dapat fokus mengembangkan logik perniagaan aplikasi anda. Anda juga akan mempraktikkan operasi CRUD sederhana menggunakan Spring LDAP dan belajar tentang operasi yang lebih maju seperti membuat penapis dinamik dan menukar entri LDAP menjadi kacang Java.

Protokol Akses Direktori Ringan adalah komponen penting dalam sebilangan besar penggunaan aplikasi perusahaan berskala besar hari ini. LDAP digunakan terutamanya untuk menyimpan maklumat yang berkaitan dengan identiti pengguna, seperti nama pengguna, kata laluan, dan alamat e-mel pengguna. Ia juga digunakan dalam pelaksanaan keselamatan di mana perlu untuk menyimpan hak akses pengguna untuk tujuan pengesahan dan kebenaran.

Java Naming and Directory Interface (JDNI) adalah API yang digunakan untuk pengaturcaraan LDAP pada platform Java. Ini menentukan antara muka standard yang boleh digunakan dalam aplikasi anda untuk berinteraksi dengan pelayan LDAP mana pun. Malangnya, menggunakan JNDI biasanya memerlukan menulis banyak kod peringkat rendah dan berulang. JNDI membuat banyak prosedur yang mudah, seperti memastikan bahawa sumber telah dibuka dan ditutup dengan betul. Sebagai tambahan, kebanyakan kaedah JNDI membuang pengecualian yang diperiksa, yang memakan masa untuk ditangani. Setelah diperiksa dengan teliti, nampaknya 50 hingga 60 peratus masa yang dihabiskan untuk memprogram JNDI terbuang dalam menangani tugas yang berulang.

Spring LDAP adalah perpustakaan Java sumber terbuka yang dirancang untuk mempermudah pengaturcaraan LDAP di platform Java. Sama seperti Spring Framework mengambil banyak pengaturcaraan tingkat rendah dari pengembangan aplikasi perusahaan Java, Spring LDAP membebaskan anda dari perincian infrastruktur menggunakan LDAP. Daripada bimbang tentang NamingExceptions dan mendapatkan InitialContext, anda bebas menumpukan perhatian pada logik perniagaan aplikasi anda. Spring LDAP juga menentukan hierarki pengecualian yang tidak diperiksa yang komprehensif dan menyediakan kelas pembantu untuk membina penapis LDAP dan nama yang terkenal.

Musim bunga LDAP dan JNDI

Perhatikan bahawa rangka kerja Spring LDAP tidak menggantikan JNDI. Sebaliknya, ia menyediakan kelas pembungkus dan utiliti di atas JNDI untuk mempermudah pengaturcaraan LDAP di platform Java.

Dalam artikel ini, panduan pemula untuk menggunakan Spring LDAP, saya akan mulakan dengan mengembangkan program JNDI sederhana untuk melaksanakan carian LDAP. Saya kemudian akan menunjukkan betapa lebih mudahnya melakukan perkara yang sama menggunakan rangka Spring LDAP. Saya akan menunjukkan kepada anda cara menggunakan Spring LDAP AttributeMapperuntuk memetakan atribut LDAP ke kacang Java, dan bagaimana menggunakan penapis dinamiknya untuk membina pertanyaan. Akhirnya, saya akan memberikan pengenalan langkah demi langkah untuk menggunakan rangka kerja Spring LDAP untuk menambah, menghapus dan mengubah data dalam pelayan LDAP anda.

Perhatikan bahawa artikel ini menganggap anda sudah biasa dengan konsep dan terminologi Spring Framework. Lihat bahagian Sumber untuk mengetahui lebih lanjut mengenai Spring Framework, LDAP dan JNDI serta memuat turun contoh aplikasi.

Pelanggan JNDI yang sederhana

Penyenaraian 1 menunjukkan program JNDI sederhana yang akan mencetak atribut cn semua Personobjek jenis pada konsol anda.

Penyenaraian 1. SimpleLDAPClient.java

public class SimpleLDAPClient { public static void main(String[] args) { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:10389/ou=system"); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system"); env.put(Context.SECURITY_CREDENTIALS, "secret"); DirContext ctx = null; NamingEnumeration results = null; try { ctx = new InitialDirContext(env); SearchControls controls = new SearchControls(); controls.setSearchScope(SearchControls.SUBTREE_SCOPE); results = ctx.search("", "(objectclass=person)", controls); while (results.hasMore()) { SearchResult searchResult = (SearchResult) results.next(); Attributes attributes = searchResult.getAttributes(); Attribute attr = attributes.get("cn"); String cn = (String) attr.get(); System.out.println(" Person Common Name = " + cn); } } catch (NamingException e) { throw new RuntimeException(e); } finally { if (results != null) { try { results.close(); } catch (Exception e) { } } if (ctx != null) { try { ctx.close(); } catch (Exception e) { } } } } }

Perkara pertama yang saya lakukan dalam Penyenaraian 1 adalah membuat InitialDirContextobjek, yang kemudian digunakan sebagai konteks untuk operasi direktori berikut. Semasa membuat Contextobjek baru saya mengkonfigurasi sifat seperti nama pengguna, kata laluan dan mekanisme pengesahan yang dapat digunakan untuk menyambung ke pelayan LDAP. Saya telah berjaya ini dengan membuat Hashtableobjek, menetapkan semua sifat ini sebagai pasangan kunci / nilai dalam Hashtabledan meneruskannya Hashtableke InitialDirContextpembina.

Masalah langsung dengan pendekatan ini adalah bahawa saya telah memasukkan semua parameter konfigurasi ke dalam fail .java. Ini berfungsi dengan baik untuk contoh saya, tetapi tidak untuk aplikasi dunia nyata. Dalam aplikasi dunia nyata, saya ingin menyimpan sifat sambungan dalam fail jndi.properties dan meletakkan fail itu di dalam classpath projek saya atau folder / libnya. Setelah membuat InitialDirContextobjek baru , API JNDI akan mencari di kedua tempat tersebut untuk fail jndi.properties, kemudian menggunakannya untuk membuat sambungan ke pelayan LDAP.

Parameter konfigurasi JNDI

Penyenaraian 2 menunjukkan parameter konfigurasi JNDI untuk menyambung ke pelayan LDAP saya. Saya menerangkan maksud parameter di bawah.

Penyenaraian 2. Parameter konfigurasi JNDI untuk LDAP

java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory java.naming.provider.url=ldap://localhost:10389/ou=system java.naming.security.authentication=simple java.naming.security.principal=uid=admin,ou=system java.naming.security.credentials=secret
  1. Konteks.INITIAL_CONTEXT_FACTORY ( java.naming.factory.initial) harus sama dengan nama kelas yang layak sepenuhnya yang akan digunakan untuk membuat konteks awal yang baru. Sekiranya tidak ada nilai yang ditentukan maka nilai NoInitialContextExceptiontersebut dilemparkan.
  2. Konteks.PROVIDER_URL ( java.naming.provider.url) harus sama dengan URL pelayan LDAP yang ingin anda sambungkan. Ia mestilah dalam format ldap://:.
  3. Konteks.SECURITY_AUTHENTICATION ( java.naming.security.authentication) mewakili jenis mekanisme pengesahan yang ingin anda gunakan. Saya telah menggunakan nama pengguna dan kata laluan untuk pengesahan dalam contoh saya, jadi nilai harta tanah ini sederhana .
  4. Konteks.SECURITY_PRINCIPAL ( java.naming.security.principal) mewakili nama pengguna yang dibezakan (DN) yang harus digunakan untuk membuat sambungan.
  5. Konteks.SECURITY_CREDENTIALS ( java.naming.security.credentials) mewakili kata laluan pengguna.

Kod pelanggan JNDI

Setelah mendapatkan Contextobjek, langkah seterusnya adalah membuat SearchControlobjek, yang merangkumi faktor-faktor yang menentukan skop carian saya dan apa yang akan dikembalikan. Saya ingin mencari keseluruhan subtree yang berakar pada konteks, jadi saya menetapkan skop carian SUBTREE_SCOPEdengan memanggil setSearchScope()kaedah SearchControl, seperti yang ditunjukkan sebelumnya dalam Penyenaraian 1.

Seterusnya, saya memanggil search()kaedah DirContext, meneruskan (objectclass=person)sebagai nilai penapis. The search()kaedah akan mengembalikan NamingEnumerationobjek yang mengandungi semua butiran dalam anak pohon daripada Context, di mana objectclassadalah sama dengan person. Setelah mendapat NamingEnumerationobjek hasil saya, saya mengulanginya dan mencetak atribut cn untuk setiap Personobjek.

Itu melengkapkan penjelasan saya mengenai kod pelanggan JNDI. Melihat SimpleLDAPClient.java, yang ditunjukkan dalam Penyenaraian 1, anda dapat dengan mudah melihat bahawa lebih daripada separuh kod menuju ke sumber pembukaan dan penutupan. Masalah lain dengan JNDI API adalah bahawa kebanyakan kaedahnya akan membuang satu NamingExceptionatau salah satu subkelasnya sekiranya berlaku kesalahan. Kerana NamingExceptionpengecualian yang dicentang, anda mesti mengatasinya jika dilemparkan, tetapi bolehkah anda benar-benar pulih dari pengecualian jika pelayan LDAP anda tidak berfungsi? Tidak, anda tidak boleh.

Sebilangan besar pemaju mengelilingi JNDI NamingExceptiondengan hanya menangkap mereka dan tidak melakukan apa-apa. Masalah dengan penyelesaian ini adalah kerana ia boleh menyebabkan anda kehilangan maklumat penting.