LDAP - JNDI Voor het kunnen aanspreken van een ldap directory service via java is er gezocht geweest naar de makkelijkste api. Deze api is beschikbaar in de standaard java 1.5 installatie en noemt java naming and directory service (jndi). De connectie maken naar een ldap directory via jndi gebeurt met een DirContext. Deze context moet wel eerst geïnstantieerd worden aan de hand van enkele properties. In het volgende code voorbeeld wordt deze context geinstantieerd. 1. 2. 3. 4. 5. 6. 7. Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:389"); env.put(Context.SECURITY_AUTHENTICATION,"simple"); env.put(Context.SECURITY_PRINCIPAL,"cn=Directory Manager"); env.put(Context.SECURITY_CREDENTIALS,"password"); DirContext ctx = new InitialDirContext(env); Enkele properties van dichtbij bekeken. PROVIDER_URL SECURITY_AUTHENTICATION Dit is de ldap directory uri. Hier wordt aangegeven welke verbinding gebruikt zal worden. Er zijn 3 mogelijke keuzes. - Simple: plain text usernames and passwords. - SSL: Authenticatie doormiddel van een SSL encryptie. - SASL: Gebruikt het MD5/Kerberos mechanisme. Is de gebruikersnaam. Het wachtwoord van de bovenstaande gebruiker. SECURITY_PRINCIPAL SECURITY_CREDENTIALS Doormiddel van de juist aangemaakte connectie is het mogenlijk om verschillende operaties op de ldap directory uit te voeren. Om een object aan de ldap directory toe te voegen moet er gebruik worden gemaakt van de bind of createsubcontext methode van de aangemaakte context. Het verschil tussen beide methodes is dat de bind methode een naam aan een object koppelt en createsubcontext zal een object aan een naam koppelen. Er bestaan 3 verschillende denkwijzen om een object in een LDAP databank aan te maken via JNDI: Het Java object zelf opslaan Een referentie naar het object opslaan De informatie als attributen opslaan 12.1.1. Het Java object zelf opslaan De eerste manier is het object zonder meer binden aan de LDAP structuur. Hierdoor wordt er een blauwdruk verkregen van het java object. Voor deze actie te kunnen ondermenen moet elke klasse, die in de ldap directory opgeslaan zal worden, de interface java.io.Serializable implementeren. 1. 2. MyObject obj = new MyObject(); ctx.bind("cn=anobject", obj); Dimitri Redant [email protected] Pagina 1 van 4 In het voorbeeld zal MyObject de java.io.Serializable interface implementeren. Aangezien enkel java deze geserialiseerde data terug kan inlezen en gebruiken is deze denkwijze enkel te gebruiken door een java applicatie. Aangezien het eindwerk een Linux Active Directory emulatie betreft is dit niet echt hetgeen gewenst is. 12.1.2. Een referentie naar het object opslaan In plaats van de volledige geserialiseerde status van een object op te slaan, kan ook de referentie naar dit object opgeslagen worden. De referentie naar een object zal volgende informatie bevatten: De klassenaam van het gerefereerde object. Een vector van javax.naming.RefAddr objecten die de adressen representeren. De naam en locatie van de object factory die gebruikt zal moeten worden voor de reconstructie. De javax.naming.RefAddr abstracte klasse, zoals hieronder weergegeven, bevatinformatie die toelaat om het object op te vragen. De klasse definieert een associatie tussen inhoud en type. De inhoud slaat informatie op benodigd voor het herbouwen van het object en het type identificeert het doel van de inhoud. Deze denkpiste is weeral niet diegene die gewenst is voor het eindwerk. 12.1.3. De informatie als attributen opslaan De laatste denkpiste is het opslaan van de attributen van een object. Dit is dus het gewenste resultaat. Aangezien een windows client geen weet heeft hoe een java geserialiseerd of gerefereerd object te interpreteren kan deze zich dan ook niet authenticeren. Authenticatie kan wel als hij de attributen rechtstreeks kan uitlezen uit de ldap directory. De klasse die gebonden moet worden zal de interface DirContext moeten implementeren. Als dit object aan de ldap directory zal worden gebonden zal deze de attributen opvragen en binden. 1. 2. 3. 4. 5. 6. 7. public class User implements DirContext{ String id; String dn; Attributes myAttrs = new BasicAttributes(true); Attribute oc = new BasicAttribute("objectclass"); Attribute ouSet = new BasicAttribute("ou"); public User(String dn,String uid, String givenname,String sn,String ou, Dimitri Redant [email protected] Pagina 2 van 4 8 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. String mail,String tel,String fax){ this.dn=dn; id = uid; oc.add("inetOrgPerson"); oc.add("organizationalPerson"); oc.add("person"); oc.add("top"); ouSet.add("People"); ouSet.add(ou); String cn = givenname+" "+sn; myAttrs.put(oc); myAttrs.put(ouSet); myAttrs.put("uid",uid); myAttrs.put("cn",cn); myAttrs.put("sn",sn); myAttrs.put("givenname",givenname); myAttrs.put("mail",mail); myAttrs.put("telephonenumber",tel); myAttrs.put("facsimilietelephonenumber",fax") } public Attributes getAttributes(String name) throws NamingException { if (! name.equals("")){ throw new NameNotFoundException(); } return myAttrs; } public Attributes getAttributes(Name name) throws NamingException { return getAttributes(name.toString()); } public Attributes getAttributes(String name, String[] ids) throws NamingException { if(! name.equals("")) throw new NameNotFoundException(); Attributes answer = new BasicAttributes(true); Attribute target; for (int i = 0; i < ids.length; i++){ target = myAttrs.get(ids[i]); if (target != null){ answer.put(target); } } return answer; } public Attributes getAttributes(Name name, String[] ids) throws NamingException { return getAttributes(name.toString(), ids); } // other methods of DirContext with blank implementations. Om dit object te koppelen aan de ldap directory kan het volgende codevoorbeeld van dienst zijn. 1. 2. 3. User usr = new User("digitalux","Dimitri","Redant","ou=Programmers", "[email protected]"); ctx.bind("uid=digitalux,ou=Programmers,o=linux.be", usr); Objecten die toe werden gevoegd moeten ook kunnen verwijderd of gewijzigd worden. Dimitri Redant [email protected] Pagina 3 van 4 Om dit te verwezenlijken moet het object uit de ldap directory gehaald worden. De “lookup” methode van de DirContext zal het gevonden object teruggeven, nadien zal het object gecast worden naar het object dat gewijzigd moet worden. Eenmaal dit object verkregen is zullen methodes aangeroepen worden die geïmplementeerd zijn in de klasse om de gegevens aan te passen. Nadien moeten deze opniew aan de ldap directory worden gekoppeld. Om een object opnieuw te binden wordt de “rebind” methode gebruikt. Een object verwijderen zal gebeuren door ofwel de unbind methode of de destroysubcontext methode aan te roepen. Deze methodes worden aangeroepen op de DirContext. 1. 2. DirContext ctx = new InitialDirContext(env); ctx.destroySubcontext("uid=digitalux, ou=Programmers, o=myserver.com"); 1. 2. Dircontext ctx = new InitialDirContext(env); ctx.unbind("uid=digitalux, ou=Programmers, o=myserver.com", usr); Het is ook mogenlijk een object te verplaatsen/hernoemen. Dit zal gebeuren doormiddel van de rename methode op de dircontext. 1. 2. 3. Dircontext ctx = new InitialDirContext(env); ctx.rename("uid=digitalux, ou=Programmers, o=myserver.com", “uid=digitalux, ou=Idiotic Programmers, o=myserver.com”); Informatie werd gevonden op volgende website: http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-ldap.html In de vroegere versie van dit document was het code van het eindwerk dat gebruikt werd. Aangezien ik voor de moment het vroegere document en de code niet meer terugvindt heb ik tijdelijk de code gecopiërd van de bovenvernoemde website. Dimitri Redant [email protected] Pagina 4 van 4