Programmering

Forenkle biblioteksadgang med Spring LDAP

Spring LDAP er en Spring-baseret ramme, der forenkler LDAP-programmering på Java-platformen. I denne trinvise vejledning til brug af Spring LDAP lærer du, hvordan rammen håndterer den lave kodning, der kræves af de fleste LDAP-klienter, så du kan fokusere på at udvikle din applikations forretningslogik. Du vil også øve på enkle CRUD-operationer ved hjælp af Spring LDAP og lære om mere avancerede operationer såsom at oprette dynamiske filtre og konvertere LDAP-poster til Java-bønner.

Den lette vægtadgangsprotokol er en vigtig komponent i de fleste store applikationsinstallationer i dag. LDAP bruges primært til at gemme oplysninger relateret til brugeridentitet, såsom en brugers brugernavn, adgangskode og e-mail-adresse. Det bruges også i sikkerhedsimplementeringer, hvor det er nødvendigt at gemme brugeradgangsrettigheder til godkendelses- og autorisationsformål.

Java Naming and Directory Interface (JDNI) er den API, der bruges til LDAP-programmering på Java-platformen. Den definerer en standardgrænseflade, der kan bruges i din applikation til at interagere med enhver LDAP-server. Desværre medfører brug af JNDI typisk at skrive en masse gentagne koder på lavt niveau. JNDI gør alt for meget arbejde med enkle procedurer, såsom at sikre, at ressourcerne er åbnet og lukket korrekt. Derudover kaster de fleste JNDI-metoder kontrollerede undtagelser, som er tidskrævende at håndtere. Ved nøje inspektion ser det ud til, at 50 til 60 procent af tiden brugt på programmering af JNDI spildes på håndtering af gentagne opgaver.

Spring LDAP er et open source Java-bibliotek designet til at forenkle LDAP-programmering på Java-platformen. Ligesom Spring Framework tager meget af programmeringen på lavt niveau ud af Java-virksomhedsapplikationsudvikling, frigør Spring LDAP dig fra de infrastrukturelle detaljer ved brug af LDAP. Snarere end at bekymre sig om Navngivelse af undtagelses og få InitialContexts, du er fri til at koncentrere dig om din applikations forretningslogik. Spring LDAP definerer også et omfattende ukontrolleret undtagelseshierarki og giver hjælperklasser til opbygning af LDAP-filtre og særprægede navne.

Forår LDAP og JNDI

Bemærk, at Spring LDAP-rammen ikke erstatter JNDI. Snarere giver det wrapper- og utilityklasser over JNDI for at forenkle LDAP-programmering på Java-platformen.

I denne artikel, en begyndervejledning til brug af Spring LDAP, begynder jeg med at udvikle et simpelt JNDI-program til udførelse af en LDAP-søgning. Jeg demonstrerer derefter, hvor meget lettere det er at gøre det samme ved hjælp af Spring LDAP-rammen. Jeg viser dig, hvordan du bruger Spring LDAP'er AttributeMappers for at kortlægge LDAP-attributter til Java-bønner, og hvordan man bruger dets dynamiske filtre til at oprette forespørgsler. Endelig giver jeg en trinvis introduktion til brug af Spring LDAP-rammen til at tilføje, slette og ændre data på din LDAP-server.

Bemærk, at denne artikel antager, at du er bekendt med koncepterne og terminologien i Spring Framework. Se afsnittet Ressourcer for at lære mere om Spring Framework, LDAP og JNDI samt for at downloade prøveapplikationen.

En simpel JNDI-klient

Liste 1 viser et simpelt JNDI-program, der udskriver cn egenskaber for alle Person skriv objekter på din konsol.

Notering 1. SimpleLDAPClient.java

offentlig klasse 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, "enkel"); env.put (Context.SECURITY_PRINCIPAL, "uid = admin, ou = system"); env.put (Context.SECURITY_CREDENTIALS, "hemmelig"); DirContext ctx = null; NamingEnumeration resultater = null; prøv {ctx = ny InitialDirContext (env); SearchControls kontrol = nye SearchControls (); controls.setSearchScope (SearchControls.SUBTREE_SCOPE); resultater = ctx.search ("", "(objectclass = person)", kontroller); mens (results.hasMore ()) {SearchResult searchResult = (SearchResult) results.next (); Attributter attributter = searchResult.getAttributter (); Attribut attr = attributter.get ("cn"); Streng cn = (String) attr.get (); System.out.println ("Person Common Name =" + cn); }} fange (NamingException e) {throw new RuntimeException (e); } endelig {if (results! = null) {prøv {results.close (); } fange (Undtagelse e) {}} hvis (ctx! = null) {prøv {ctx.close (); } fangst (undtagelse e) {}}}}}

Den første ting, jeg har gjort i Listing 1, er at oprette en InitialDirContext objekt, som derefter bruges som kontekst for følgende bibliotekshandlinger. Når du opretter en ny Sammenhæng objekt Jeg konfigurerer egenskaber såsom brugernavn, adgangskode og godkendelsesmekanisme, der kan bruges til at oprette forbindelse til LDAP-serveren. Jeg har formået dette ved at oprette en Hashtable objekt, der opsætter alle disse egenskaber som nøgle / værdipar i Hashtable og passerer Hashtable til InitialDirContext konstruktør.

Det umiddelbare problem med denne tilgang er, at jeg har hårdt kodet alle konfigurationsparametrene i en .java-fil. Dette fungerer fint for mit eksempel, men ikke for en applikation i den virkelige verden. I en applikation i den virkelige verden vil jeg gemme forbindelsesegenskaberne i en jndi.properties-fil og placere den i enten mit projekts klassesti eller dens / lib-mappe. Ved oprettelsen af ​​et nyt InitialDirContext objekt, ville JNDI API søge begge disse steder efter filen jndi.properties og derefter bruge den til at oprette en forbindelse til LDAP-serveren.

JNDI-konfigurationsparametre

Liste 2 viser JNDI-konfigurationsparametrene til forbindelse til min LDAP-server. Jeg forklarer betydningen af ​​parametrene nedenfor.

Liste 2. JNDI-konfigurationsparametre for LDAP

java.naming.factory.initial = com.sun.jndi.ldap.LdapCtxFactory java.naming.provider.url = ldap: // localhost: 10389 / ou = system java.naming.security.authentication = enkel java.naming.security .principal = uid = admin, ou = system java.naming.security.credentials = hemmelig
  1. Kontekst.INITIAL_CONTEXT_FACTORY (java.naming.factory.initial) skal svare til det fuldt kvalificerede klassenavn, der skal bruges til at skabe en ny indledende kontekst. Hvis der ikke er angivet nogen værdi, bliver NoInitialContextException kastes.
  2. Kontekst.PROVIDER_URL (java.naming.provider.url) skal svare til URL'en til den LDAP-server, du vil oprette forbindelse til. Det skal være i formatet ldap: //:.
  3. Kontekst.SECURITY_AUTHENTICATION (java.naming.security.authentication) repræsenterer den type godkendelsesmekanisme, du vil bruge. Jeg har brugt et brugernavn og en adgangskode til godkendelse i mit eksempel, så værdien af ​​denne ejendom er enkel.
  4. Kontekst.SECURITY_PRINCIPAL (java.naming.security.principal) repræsenterer det fremtrædende brugernavn (DN), der skal bruges til at oprette en forbindelse.
  5. Kontekst.SECURITY_CREDENTIALS (java.naming.security.credentials) repræsenterer brugerens adgangskode.

JNDI-klientkoden

Efter at have fået Sammenhæng objekt mit næste trin er at oprette en Søgekontrol objekt, der indkapsler de faktorer, der bestemmer omfanget af min søgning, og hvad der returneres. Jeg vil søge i hele undertræet, der er rodfæstet i konteksten, så jeg indstiller søgeområdet til SUBTREE_SCOPE ved at ringe til setSearchScope () metode til Søgekontrol, som tidligere vist i liste 1.

Dernæst kalder jeg Søg() metode til DirContext, passerer ind (objektklasse = person) som filterets værdi. Det Søg() metoden returnerer a NamingEnumeration objekt, der indeholder alle posterne i undertræet til Sammenhæng, hvor objektklasse er lig med person. Efter at have fået en NamingEnumeration som mit resultatobjekt gentager jeg det og udskriver en cn attribut for hver Person objekt.

Det fuldender min forklaring af JNDI-klientkoden. Ser man på SimpleLDAPClient.java, vist i Listing 1, kan du nemt se, at mere end halvdelen af ​​koden går mod åbning og lukning af ressourcer. Et andet problem med JNDI API er, at de fleste af dens metoder vil kaste et Navngivelse af undtagelse eller en af ​​dens underklasser i tilfælde af en fejl. Fordi Navngivelse af undtagelse er en markeret undtagelse, skal du håndtere den, hvis den smides, men kan du virkelig komme sig fra en undtagelse, hvis din LDAP-server er nede? Nej, det kan du ikke.

De fleste udviklere kommer omkring JNDI Navngivelse af undtagelses ved blot at fange dem og ikke gøre noget. Problemet med denne løsning er, at det kan få dig til at miste vigtige oplysninger.