Programování

Zjednodušte přístup k adresáři pomocí Spring LDAP

Jarní LDAP je jarní rámec, který zjednodušuje programování LDAP na platformě Java. V tomto podrobném průvodci používáním Spring LDAP se naučíte, jak framework zpracovává nízkoúrovňové kódování vyžadované většinou klientů LDAP, abyste se mohli soustředit na vývoj obchodní logiky vaší aplikace. Procvičíte si také jednoduché operace CRUD pomocí Spring LDAP a dozvíte se o pokročilejších operacích, jako je vytváření dynamických filtrů a převod položek LDAP na Java fazole.

Protokol Lightweight Directory Access Protocol je dnes základní součástí většiny rozsáhlých podnikových nasazení aplikací. LDAP se primárně používá k ukládání informací souvisejících s identitou uživatele, jako je uživatelské jméno, heslo a e-mailová adresa uživatele. Používá se také v implementacích zabezpečení, kde je nutné ukládat přístupová práva uživatelů pro účely ověřování a autorizace.

Java Naming and Directory Interface (JDNI) je API používané pro programování LDAP na platformě Java. Definuje standardní rozhraní, které lze ve vaší aplikaci použít k interakci s libovolným serverem LDAP. Bohužel používání JNDI obvykle vyžaduje psaní spousty opakujících se nízkoúrovňových kódů. JNDI dělá příliš mnoho práce s jednoduchými postupy, jako je zajištění toho, že zdroje byly správně otevřeny a zavřeny. Kromě toho většina metod JNDI vyvolá kontrolované výjimky, jejichž zpracování je časově náročné. Po důkladné kontrole se zdá, že 50 až 60 procent času stráveného programováním JNDI je zbytečné při manipulaci s opakujícími se úkoly.

Spring LDAP je open source knihovna Java navržená ke zjednodušení programování LDAP na platformě Java. Stejně jako Spring Framework bere většinu nízkoúrovňového programování z vývoje podnikových aplikací Java, Spring LDAP vás osvobozuje od infrastrukturních detailů používání LDAP. Spíše než si dělat starosti NamingExceptionsa dostat InitialContexts, můžete se soustředit na obchodní logiku své aplikace. Jarní LDAP také definuje komplexní nekontrolovanou hierarchii výjimek a poskytuje pomocné třídy pro vytváření filtrů LDAP a rozlišujících jmen.

Jarní LDAP a JNDI

Všimněte si, že jarní rámec LDAP nenahrazuje JNDI. Spíše poskytuje obálky a třídy nástrojů přes JNDI, aby zjednodušil programování LDAP na platformě Java.

V tomto článku, příručce pro začátečníky k používání Spring LDAP, začnu vývojem jednoduchého programu JNDI pro provádění vyhledávání LDAP. Poté ukážu, o kolik je jednodušší dělat to samé pomocí jarního rámce LDAP. Ukážu vám, jak používat jarní LDAP AttributeMappers mapovat atributy LDAP na fazole Java a jak používat jeho dynamické filtry k vytváření dotazů. Na závěr uvedu podrobný úvod do používání jarního rozhraní LDAP pro přidávání, mazání a úpravy dat na vašem serveru LDAP.

Tento článek předpokládá, že jste obeznámeni s koncepty a terminologií Spring Framework. V sekci Zdroje se dozvíte více o Spring Framework, LDAP a JNDI a také o stažení ukázkové aplikace.

Jednoduchý klient JNDI

Výpis 1 zobrazuje jednoduchý program JNDI, který vytiskne soubor cn atributy všech Osoba zadejte objekty na konzole.

Výpis 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, "jednoduché"); env.put (Context.SECURITY_PRINCIPAL, "uid = admin, ou = systém"); env.put (Context.SECURITY_CREDENTIALS, "tajemství"); DirContext ctx = null; NamingEnumeration results = null; try {ctx = new InitialDirContext (env); Ovládací prvky SearchControls = nové SearchControls (); controls.setSearchScope (SearchControls.SUBTREE_SCOPE); results = ctx.search ("", "(objectclass = person)", ovládací prvky); while (results.hasMore ()) {SearchResult searchResult = (SearchResult) results.next (); Atributy atributy = searchResult.getAttributes (); Atribut attr = attributes.get ("cn"); Řetězec cn = (Řetězec) attr.get (); System.out.println ("Společné jméno osoby =" + cn); }} catch (NamingException e) {hodit novou RuntimeException (e); } konečně {if (results! = null) {try {results.close (); } catch (Výjimka e) {}} if (ctx! = null) {try {ctx.close (); } úlovek (Výjimka e) {}}}}}

První věc, kterou jsem udělal v seznamu 1, je vytvořit InitialDirContext objekt, který se poté použije jako kontext pro následující operace s adresáři. Při vytváření nového Kontext objekt Konfiguruji vlastnosti, jako je uživatelské jméno, heslo a ověřovací mechanismus, které lze použít k připojení k serveru LDAP. Podařilo se mi to vytvořením Hashtable objekt, nastavení všech těchto vlastností jako párů klíč / hodnota v Hashtable a absolvování Hashtable do InitialDirContext konstruktor.

Okamžitým problémem tohoto přístupu je, že jsem napevno naprogramoval všechny konfigurační parametry do souboru .java. To funguje dobře pro můj příklad, ale ne pro skutečnou aplikaci. V aplikaci v reálném světě bych chtěl uložit vlastnosti připojení do souboru jndi.properties a umístit tento soubor buď do classpath mého projektu, nebo do jeho / lib složky. Po vytvoření nového InitialDirContext objekt, rozhraní API JNDI vyhledá na obou těchto místech soubor jndi.properties a poté jej použije k vytvoření připojení k serveru LDAP.

Konfigurační parametry JNDI

Výpis 2 zobrazuje konfigurační parametry JNDI pro připojení k mému serveru LDAP. Níže vysvětluji význam parametrů.

Výpis 2. Konfigurační parametry JNDI pro LDAP

java.naming.factory.initial = com.sun.jndi.ldap.LdapCtxFactory java.naming.provider.url = ldap: // localhost: 10389 / ou = systém java.naming.security.authentication = jednoduchá java.naming.security .principal = uid = admin, ou = systém java.naming.security.credentials = tajný
  1. Context.INITIAL_CONTEXT_FACTORY (java.naming.factory.initial) by se měl rovnat plně kvalifikovanému názvu třídy, který bude použit k vytvoření nového počátečního kontextu. Pokud není zadána žádná hodnota, pak NoInitialContextException je hozen.
  2. Kontext.PROVIDER_URL (java.naming.provider.url) by se měla rovnat URL serveru LDAP, ke kterému se chcete připojit. Mělo by to být ve formátu ldap: //:.
  3. Kontext.SECURITY_AUTHENTICATION (java.naming.security.authentication) představuje typ ověřovacího mechanismu, který chcete použít. V mém příkladu jsem pro ověření použil uživatelské jméno a heslo, takže hodnota této vlastnosti je jednoduchý.
  4. Kontext.SECURITY_PRINCIPAL (java. pojmenování. bezpečnost. hlavní) představuje rozlišující uživatelské jméno (DN), které by mělo být použito k navázání připojení.
  5. Context.SECURITY_CREDENTIALS (java.naming.security.credentials) představuje heslo uživatele.

Kód klienta JNDI

Po získání Kontext objekt mým dalším krokem je vytvořit a SearchControl objekt, který zapouzdřuje faktory, které určují rozsah mého hledání a to, co bude vráceno. Chci prohledat celý podstrom zakořeněný v kontextu, takže jsem nastavil rozsah hledání na SUBTREE_SCOPE voláním setSearchScope () metoda SearchControl, jak již bylo uvedeno v seznamu 1.

Dále volám Vyhledávání() metoda DirContext, procházející dovnitř (třída objektu = osoba) jako hodnota filtru. The Vyhledávání() metoda vrátí a NamingEnumeration objekt obsahující všechny položky v podstromu Kontext, kde třída objektů je rovný osoba. Po získání NamingEnumeration jako můj výsledný objekt iteruji a vytisknu a cn atribut pro každého Osoba objekt.

Tím je moje vysvětlení kódu klienta JNDI dokončeno. Při pohledu na SimpleLDAPClient.java, který je uveden v seznamu 1, můžete snadno vidět, že více než polovina kódu směřuje k otevírání a zavírání prostředků. Dalším problémem s rozhraním JNDI API je, že většina jeho metod vyvolá a NamingException nebo jednu z jejích podtříd v případě chyby. Protože NamingException je zaškrtnutá výjimka, musíte ji zvládnout, pokud je vyvolána, ale můžete se opravdu zotavit z výjimky, pokud je váš server LDAP nefunkční? Ne, nemůžete.

Většina vývojářů obchází JNDI NamingExceptionjednoduše je chytit a nedělat nic. Potíž s tímto řešením spočívá v tom, že může dojít ke ztrátě důležitých informací.