Ohjelmointi

Yksinkertaista hakemiston käyttöä Spring LDAP: llä

Spring LDAP on kevään pohjainen kehys, joka yksinkertaistaa LDAP-ohjelmointia Java-alustalla. Tässä kevään LDAP: n käytön vaiheittaisessa oppaassa opit, kuinka kehys käsittelee useimpien LDAP-asiakkaiden vaatimaa matalan tason koodausta, jotta voit keskittyä sovelluksesi liiketoimintalogiikan kehittämiseen. Harjoittelet myös yksinkertaisia ​​CRUD-toimintoja Spring LDAP: n avulla ja opit edistyneemmistä toiminnoista, kuten dynaamisten suodattimien luomisesta ja LDAP-merkintöjen muuntamisesta Java-pavuiksi.

Kevyt hakemistoprotokolla on olennainen osa useimpia suurten yrityssovellusten käyttöönottoja nykyään. LDAP: tä käytetään ensisijaisesti käyttäjän identiteettiin liittyvien tietojen, kuten käyttäjän käyttäjänimen, salasanan ja sähköpostiosoitteen, tallentamiseen. Sitä käytetään myös tietoturvatoteutuksissa, joissa on tarpeen tallentaa käyttäjän käyttöoikeudet todennusta ja todennusta varten.

Java Naming and Directory Interface (JDNI) on API, jota käytetään LDAP-ohjelmointiin Java-alustalla. Se määrittelee vakioliitännän, jota voidaan käyttää sovelluksessasi vuorovaikutuksessa minkä tahansa LDAP-palvelimen kanssa. Valitettavasti JNDI: n käyttö edellyttää tyypillisesti paljon matalan tason toistuvien koodien kirjoittamista. JNDI tekee aivan liian paljon työtä yksinkertaisissa menettelyissä, kuten varmistaa, että resurssit on avattu ja suljettu asianmukaisesti. Lisäksi useimmat JNDI-menetelmät heittävät tarkistetut poikkeukset, joiden käsittely on aikaa vievää. Tarkkaan tarkasteltuna näyttää siltä, ​​että 50-60 prosenttia JNDI: n ohjelmointiin käytetystä ajasta tuhlataan toistuvien tehtävien käsittelyyn.

Spring LDAP on avoimen lähdekoodin Java-kirjasto, joka on suunniteltu yksinkertaistamaan LDAP-ohjelmointia Java-alustalla. Aivan kuten Spring Framework vie suuren osan matalan tason ohjelmoinnista Java-yrityssovellusten kehittämiseen, Spring LDAP vapauttaa sinut LDAP: n käytön infrastruktuurista. Sen sijaan, että huolehtisi NamingExceptions ja saaminen InitialContexts, voit vapaasti keskittyä sovelluksesi liiketoimintalogiikkaan. Kevään LDAP määrittelee myös kattavan tarkistamattoman poikkeushierarkian ja tarjoaa auttajaluokat LDAP-suodattimien ja erottuvien nimien rakentamiseen.

Kevään LDAP ja JNDI

Huomaa, että kevään LDAP-kehys ei korvaa JNDI: tä. Pikemminkin se tarjoaa pakkaus- ja apuohjelmaluokat JNDI: n kautta yksinkertaistamaan LDAP-ohjelmointia Java-alustalla.

Tässä artikkelissa, joka on aloittelijan opas kevään LDAP: n käyttöön, aloitan kehittämällä yksinkertaisen JNDI-ohjelman LDAP-haun suorittamiseksi. Esittelen sitten, kuinka paljon helpompaa on tehdä sama asia kevään LDAP-kehyksen avulla. Näytän sinulle, miten kevään LDAP: itä käytetään AttributeMappers LDAP-attribuuttien kartoittamiseksi Java-pavuille ja kuinka käyttää sen dynaamisia suodattimia kyselyjen luomiseen. Lopuksi esitän vaiheittaisen johdannon kevään LDAP-kehyksen käyttämiseen LDAP-palvelimen tietojen lisäämiseen, poistamiseen ja muokkaamiseen.

Huomaa, että tässä artikkelissa oletetaan, että olet perehtynyt kevään kehyksen käsitteisiin ja terminologiaan. Resurssit-osiosta saat lisätietoja Spring Frameworkista, LDAP: stä ja JNDI: stä sekä lataamalla mallisovelluksen.

Yksinkertainen JNDI-asiakas

Listaus 1 näyttää yksinkertaisen JNDI-ohjelman, joka tulostaa cn kaikkien Henkilö kirjoita esineitä konsoliin.

Listaus 1. SimpleLDAPClient.java

julkinen luokka SimpleLDAPClient {public static void main (String [] args) {Hashtable env = new Hashtable (); env.put (Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put (Konteksti.PROVIDER_URL, "ldap: // localhost: 10389 / ou = system"); env.put (konteksti.SECURITY_AUTHENTICATION, "yksinkertainen"); env.put (Context.SECURITY_PRINCIPAL, "uid = admin, ou = järjestelmä"); env.put (konteksti.SECURITY_CREDENTIALS, "salainen"); DirContext ctx = nolla; NameingEnumeration -tulokset = null; kokeile {ctx = new InitialDirContext (env); SearchControls controls = uusi SearchControls (); controls.setSearchScope (SearchControls.SUBTREE_SCOPE); tulokset = ctx.search ("", "(objektiluokka = henkilö)", ohjaimet); while (results.hasMore ()) {SearchResult searchResult = (SearchResult) tulokset.seuraava (); Attribuutit attribuutit = searchResult.getAttributes (); Attribuutti attr = attributes.get ("cn"); Merkkijono cn = (merkkijono) attr.get (); System.out.println ("Henkilön yleinen nimi =" + cn); }} catch (NamingException e) {heitä uusi RuntimeException (e); } lopuksi {if (results! = null) {kokeile {results.close (); } catch (Exception e) {}} if (ctx! = null) {kokeile {ctx.close (); } catch (Poikkeus e) {}}}}}

Ensimmäinen asia, jonka olen tehnyt luettelossa 1, on luoda InitialDirContext objekti, jota käytetään sitten seuraavien hakemistotoimintojen kontekstina. Kun luot uuden Asiayhteys objekti Määritän ominaisuuksia, kuten käyttäjänimen, salasanan ja todennusmekanismin, joita voidaan käyttää yhteyden muodostamiseen LDAP-palvelimeen. Olen onnistunut tässä luomalla Hashtable objekti, asettamalla kaikki nämä ominaisuudet avain / arvo-pareiksi Hashtable ja ohittaa Hashtable että InitialDirContext rakentaja.

Tämän lähestymistavan välitön ongelma on, että olen koodannut kaikki kokoonpanoparametrit kovasti .java-tiedostoon. Tämä toimii hyvin esimerkissäni, mutta ei tosielämän sovelluksessa. Todellisessa sovelluksessa haluan tallentaa yhteysominaisuudet jndi.properties-tiedostoon ja sijoittaa kyseisen tiedoston joko projektini luokkatielle tai sen / lib -kansioon. Kun luot uuden InitialDirContext objekti, JNDI-sovellusliittymä etsii jndi.properties-tiedostoa molemmista näistä paikoista ja luo sitten yhteyden LDAP-palvelimeen.

JNDI-kokoonpanoparametrit

Listaus 2 näyttää JNDI-kokoonpanoparametrit yhteyden muodostamiseksi LDAP-palvelimelleni. Selitän alla olevien parametrien merkityksen.

Luettelo 2. JNDI-määritysparametrit LDAP: lle

java.naming.factory.initial = com.sun.jndi.ldap.LdapCtxFactory java.naming.provider.url = ldap: // localhost: 10389 / ou = system java.naming.security.authentication = yksinkertainen java.naming.security .principal = uid = admin, ou = järjestelmä java.naming.security.credentials = salainen
  1. Konteksti.INITIAL_CONTEXT_FACTORY (java.naming.factory.initial) pitäisi olla yhtä suuri kuin täysin hyväksytty luokan nimi, jota käytetään uuden alkukontekstin luomiseen. Jos arvoa ei ole määritetty, NoInitialContextException heitetään.
  2. Konteksti.PROVIDER_URL (java.naming.provider.url) tulee olla sama kuin sen LDAP-palvelimen URL-osoite, johon haluat muodostaa yhteyden. Sen tulisi olla muodossa ldap: //:.
  3. Konteksti.SECURITY_AUTHENTICATION (java.naming.security.authentication) edustaa käytetyn todennusmekanismin tyyppiä. Olen käyttänyt todennuksessa käyttäjänimeä ja salasanaa esimerkissäni, joten tämän ominaisuuden arvo on yksinkertainen.
  4. Konteksti: SECURITY_PRINCIPAL (java.naming.security.principal) edustaa erotettua käyttäjänimeä (DN), jota tulisi käyttää yhteyden muodostamiseen.
  5. Konteksti: SECURITY_CREDENTIALS (java.naming.security.credentials) edustaa käyttäjän salasanaa.

JNDI-asiakaskoodi

Saatuasi Asiayhteys objekti seuraava askel on luoda SearchControl objekti, joka kerää tekijät, jotka määrittävät haun laajuuden ja mitä palautetaan. Haluan etsiä koko alipuuta, joka on juurtunut kontekstiin, joten asetin haun laajuudeksi SUBTREE_SCOPE soittamalla setSearchScope () menetelmä SearchControl, kuten aiemmin on esitetty luettelossa 1.

Seuraavaksi soitan Hae() menetelmä DirContext, kulkee sisään (objektiluokka = henkilö) suodattimen arvona. Hae() menetelmä palauttaa a Nimeä laskenta objekti, joka sisältää kaikki merkinnät alipuun Asiayhteys, missä objektiluokka on yhtä suuri kuin henkilö. Saatuasi a Nimeä laskenta tulosobjektina iteroin sen läpi ja tulostan a cn attribuutti kullekin Henkilö esine.

Se täydentää selitykseni JNDI-asiakaskoodista. Tarkasteltaessa Listing 1: ssä olevaa SimpleLDAPClient.java-ohjelmaa näet helposti, että yli puolet koodista menee resurssien avaamiseen ja sulkemiseen. Toinen ongelma JNDI-sovellusliittymässä on, että suurin osa sen menetelmistä heittää a NamingException tai jokin sen alaluokista virheen sattuessa. Koska NamingException on tarkistettu poikkeus, sinun on käsiteltävä sitä, jos se heitetään, mutta voitko todella toipua poikkeuksesta, jos LDAP-palvelimesi ei toimi? Ei, et voi.

Suurin osa kehittäjistä kiertää JNDI: tä NamingExceptions yksinkertaisesti kiinni heistä ja tekemättä mitään. Tämän ratkaisun ongelmana on, että se voi aiheuttaa tärkeiden tietojen menettämisen.