36
Lotus Software - Messaging & Collaboration Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation From Now To Next Ken Lin Senior Software Engineer [email protected] Collaborative Cuisine's 1 Hour JNDI Cookbook

Collaborative Cuisine's 1 Hour JNDI Cookbook

  • Upload
    ken-lin

  • View
    113

  • Download
    3

Embed Size (px)

DESCRIPTION

For programmers who are already familiar with JNDI and LDAP basics, but wonder how to mix all those ingredients together into collaborative directory-enabled JEE solutions. http://kenlin.com

Citation preview

Page 1: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging & Collaboration

Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation

From Now To Next

Ken LinSenior Software [email protected]

Collaborative Cuisine's1 Hour JNDI Cookbook

Page 2: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

Goals

Review common directory-related collaboration scenariosExamine solutions through algorithms and JNDI codeRefine and improve solutions

Page 3: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging & Collaboration

Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation

From Now To Next

StartersMain CoursesDessertsTidy Up

Today's Menu

Page 4: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging & Collaboration

Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation

From Now To Next

Locate a Directory ServerResolve and Authenticate a User

Starters

Page 5: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

Locate a Directory Server

Properties FileConfigured by each application administratorApplication-dependent solutionEasy to code via java.util.PropertiesManageable when few applications

RFC 2782 - A DNS RR for specifying the location of services (DNS SRV)

Configured centrally by DNS administratorApplication-independent solutionEasy to code via JNDIManageable even when many applicationsRecognized by com.sun.jndi.ldap.LdapCtxFactory inJDK 1.4.1

Page 6: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DNS SRV (RFC 2782)w32 [C:\] \winnt\system32\nslookupDefault Server: ns1.iris.comAddress: 9.95.aaa.bbb

> set q=srv> _ldap._tcp.iris.com you type this

0=highest65535=lowest

Server: ns1.iris.comAddress: 9.95.aaa.bbb

_ldap._tcp.iris.com SRV service location: priority = 0 weight = 0 port = 389 svr hostname = clapton.iris.com_ldap._tcp.iris.com SRV service location: priority = 100 weight = 0 port = 389 svr hostname = little-village.iris.comclapton.iris.com internet address = 9.95.ccc.dddlittle-village.iris.com internet address = 9.95.eee.fff>^Z

Page 7: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirServer.getServers returns host:port stringspublic static Vector getServers(String domain) throws NamingException {

Vector servers = new Vector();

Hashtable env = new Hashtable();env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");

DirContext ctx = new InitialDirContext(env);

Attributes attrs = ctx.getAttributes("_ldap._tcp." + domain, new String[] {"SRV"});Attribute srv = attrs.get("SRV");if (srv != null) {

NamingEnumeration results = srv.getAll();if (results.hasMore()) {

while (results.hasMore()) {String result = (String)results.next();StringTokenizer tokens = new StringTokenizer(result, " ");String priority = tokens.nextToken();String weight = tokens.nextToken();String port = tokens.nextToken();String target = tokens.nextToken();servers.add(target + ":" + port);

}}

}return servers;

}

J2SE 1.4.1 or higher

Page 8: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

Resolve and Authenticate Users

How do we code applications to authenticate using "friendly" names?

cn=ken lin,ou=westford,o=ibm is not very friendly!

Page 9: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

Resolve and Authenticate Users AlgorithmDoes the supplied name look like an LDAP DN?

Yes: ask the LDAP server if DN exists?Yes: go to Authenticated BindNo: go to Resolve DN

No: go to Resolve LDAP DNResolve supplied name to LDAP DN

Unauthenticated search the name to obtain its DN (&(objectclass=person)(|(uid={0})(mail={0})(cn={0})))Allow the filter to be customized to fit customer (&(objectclass=person)(telephonenumber={0}))If number of search hits is ...

0: name not found1: go to Authenticated Bindotherwise: ambiguous DN

Authenticated BindUse LDAP DN and supplied password

Page 10: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirUser.authenticate to Authenticate and Resolve a Nameboolean authenticate(String hostport, String anyname, String password) throws

NamingException{

boolean authenticated = false;DirContext ctx = null;try {

String dn = resolve(anyname);if (dn != null) {

Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, m_ServiceProvider);

env.put(Context.PROVIDER_URL, "ldap://" + hostport);

env.put(Context.SECURITY_AUTHENTICATION, "simple");env.put(Context.SECURITY_PRINCIPAL, dn);env.put(Context.SECURITY_CREDENTIALS, password);

ctx = new InitialDirContext(env);authenticated = true;

}} catch (AuthenticationException e) {

authenticated = false;} finally {

try {if (ctx != null) ctx.close();

} catch (Exception e) {}

}return authenticated;

}

"com.sun.jndi.ldap.LdapCtxFactory"

local DirContext for dn/password

Page 11: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirUser.resolve to Get a DN from anynameString resolve(String anyname) throws NamingException{

// If anyname looks like it might be a DN, try a base searchif (anyname.indexOf("=") != -1) {

try {Attributes attrs = m_Ctx.getAttributes(anyname);return anyname;

} catch (NameNotFoundException e) {// not a valid or known DN, try filtered search

}}

// anyname must not look like a DN, search for m_FilterPattern with anynameObject args[] = {anyname};String filter = java.text.MessageFormat.format(m_FilterPattern, args);

SearchControls ctls = new SearchControls();ctls.setReturningAttributes(null);ctls.setCountLimit(1);ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

NamingEnumeration results = m_Ctx.search(m_Base, filter, ctls);if (results.hasMore()) {

SearchResult result = (SearchResult)results.next();return result.getName();

} else {throw new NameNotFoundException("Neither DN nor filter hits");

}}

"(&(objectclass=person)(|(uid={0})(mail={0})(cn={0})))"

DirContext for this application

some vendors require base

so more than 1 result causesSizeLimitExceededException

Page 12: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging & Collaboration

Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation

From Now To Next

Find a Member's GroupFind a Group's Members

Main Courses

Page 13: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

Directory Groups

IETF, Defacto, and Vendor Group DefinitionsDefinitions for Static Groups in IETF RFC 2782

groupOfNames / membergroupOfUniqueNames / uniqueMember

Group operations are coded by the application, not the LDAP server!

Applications must understand schemaApplications must code findMembersApplications must code findGroups

Page 14: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

dgservlet Demo

Page 15: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

Two Common Uses for findMembers and findGroupsfindMembers can be used to expand and flatten out a buddy list

findGroups can be used to create Notes-like NamesLists for authorization

Page 16: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirGroups Classpublic class DirGroups{

protected DirContext m_Ctx = null;

protected NameParser m_Parser = null;protected String m_GroupObjectClasses[] = {"groupOfNames"};protected String m_MemberNames[] = {"member"};protected String m_Base = "";protected String m_MemberFilter = "(&(objectclass=groupOfNames)(member={0}))";protected int m_FindMembersDepth = 10;protected String m_MemberAttrIds[] = {"objectclass", "member", "cn"};

public DirGroups(DirContext ctx) {m_Ctx = ctx;

}

public void findGroups(String memberDN, Hashtable groups) throws NamingException{ described later... }

public void findMembers(Name groupDN, Hashtable groups,Hashtable users, Hashtable unknown) throws NamingException

{ described later... }

etc...}

Page 17: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

findMembers Algorithm

get entry g from groupDN and verify it is a groupforeach memberDN in g { if memberDN isn't in groups, users, or unknown { get entry m from memberDN if m is a group --> add m to groups and recurse... findMembers(memberDN, groups, users, unknown) if m is a non-group --> add m to users if m's objectclass is unknown --> add m to unknown }}

findMembers(in String groupDN, inout Hashtable groups, inout Hashtable users, inout Hashtable unknown)

Optimize!

Page 18: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirGroups.findMemberspublic void findMembers(Name groupDN,

Hashtable groups,Hashtable users,Hashtable unknown)

throws NamingException{

// Verify argumentsif (groupDN == null ||

groups == null || users == null || unknown == null){

return;}

// Verify the groupDN is really a groupAttributes attrs = m_Ctx.getAttributes(groupDN, m_MemberAttrIds);if (!isGroup(attrs)) {

throw new NamingException("'objectclass' is not a group");}

findMembers(attrs, m_FindMembersDepth, groups, users, unknown);}

DirContext for this DirGroups object

10

{"objectclass", "member", "cn"}

Page 19: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirGroups.findMembersprivate void findMembers(Attributes attrs, int depth, Hashtable groups,

Hashtable users,Hashtable unknown) throws NamingException {if (depth <= 0) { return; }for (int i = 0; i < m_MemberNames.length; i++) {

Attribute attr = attrs.get(m_MemberNames[i]);if (attr != null) {

NamingEnumeration members = attr.getAll();while (members.hasMore()) {

Name memberDN = toName((String)members.nextElement());// Process memberDN only if it hasn't yet been encounterredif (!users.containsKey(memberDN) && !groups.containsKey(memberDN) &&

!unknown.containsKey(memberDN)) {try {

if (isGroup(memberDN)) { // memberDN is a groupattrs = m_Ctx.getAttributes(memberDN, m_MemberAttrIds);if (groups.put(memberDN, attrs) == null) {

findMembers(attrs, depth-1, groups, users, unknown);}

} else { // memberDN is a non-groupusers.put(memberDN, memberDN/*null*/);

}} catch (NamingException e) { // memberDN is unknown

unknown.put(memberDN, memberDN/*null*/);}

}} // while

}} // for

}

{"objectclass","member", "cn"}

{"member"}

Page 20: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirGroups.isGroupprivate boolean isGroup(Name name)

throws NamingException{

if (m_GroupObjectClasses.length == 1) {return compare(name, "objectclass", m_GroupObjectClasses[0]);

} else {Attributes attrs = m_Ctx.getAttributes(name, m_MemberAttrIds);return isGroup(attrs);

}}

private boolean isGroup(Attributes attrs)throws NamingException

{Attribute attr = attrs.get("objectclass");if (attr != null) {

for (int i = 0; i < m_GroupObjectClasses.length; i++) {if (attr.contains(m_GroupObjectClasses[i])) {

return true;}

}return false;

} else {throw new NamingException("'objectclass' attribute not found");

}}

LDAP compare is faster than search

{"groupOfNames"}

Page 21: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirGroups.compareprivate boolean compare(Name name, String attr, String value)

throws NamingException{

SearchControls ctls = new SearchControls();ctls.setSearchScope(SearchControls.OBJECT_SCOPE);ctls.setReturningAttributes(new String[0]); // no attributes

// LDAP compare operationNamingEnumeration results = m_Ctx.search(name, "(" + attr + "=" + value + ")",

ctls);return results.hasMore(); // if successful, results will contain a single item

}

Page 22: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

findGroups AlgorithmfindGroups(in String memberDN, inout Hashtable groups)

g = DNs of groups that memberDNis a direct member

tovisit = gwhile tovisit is not empty { pop any groupDN from tovisit if groupDN is not in groups { groups += groupDN g = DNs of groups that groupDN

is a direct member of tovisit += elements of g not in

tovisit or groups }}

1. cn=bugs bunny,o=toons empty

2. cn=looney toons

3. cn=looney toons

4. cn=looney toons empty

5. cn=looney toons

6. cn=all toons

7. cn=all toons

8. cn=all toons

9. cn=all toons empty

10. cn=looney toons cn=all toons11. empty

12. empty

Page 23: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirGroups.findGroupspublic void findGroups(Name memberDN,

Hashtable groups)throws NamingException

{Hashtable tovisit = new Hashtable(); // DNs of groups to visit

// Initialize tovisit to groups that memberDN is a direct member of.putDirectGroups(memberDN, tovisit, groups);

// groups = union(groups, tovisit)while (!tovisit.isEmpty()) {

// Pop groupDN from tovisitName groupDN = (Name)tovisit.keys().nextElement();tovisit.remove(groupDN);

// Add groupDN to groupsif (groups.put(groupDN, groupDN) == null) {

// Wasn't previously processed, search what groups it is a// member of.try {

putDirectGroups(groupDN, tovisit, groups);} catch (NamingException e) {

e.printStackTrace();}

} else {// Was processed previously, don't do anything

}}

}

Page 24: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirGroups.putDirectGroupsprivate void putDirectGroups(Name memberDN,

Hashtable tovisit, Hashtable groups)

throws NamingException{

// Find in results the groups that memberDN is a direct member of.NamingEnumeration results = findDirectGroups(memberDN);

// Put each group in tovisit if it doesn't already exist in tovisit or// groups.while (results.hasMore()) {

SearchResult result = (SearchResult)results.next();Name groupDN = toName(result.getName());if (!groups.containsKey(groupDN) && !tovisit.contains(groupDN)) {

tovisit.put(groupDN, groupDN);}

}}

Page 25: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirGroups.findDirectGroupsprivate NamingEnumeration findDirectGroups(Name memberDN)

throws NamingException{

Object args[] = {memberDN};String filter = java.text.MessageFormat.format(m_MemberFilter, args);

SearchControls ctls = new SearchControls();String[] attrIDs = {};ctls.setReturningAttributes(attrIDs);ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

NamingEnumeration results = m_Ctx.search(m_Base, filter, ctls);return results;

}

"(&(objectclass=groupOfNames) (member={0}))"

some vendors require base

DirContext for this DirGroups object

Page 26: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging & Collaboration

Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation

From Now To Next

Domino LDAP Server TipsClient-side LDAP ImprovementsTwo and Three-Tier Architectures

Desserts

Page 27: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

DirUser.m_FilterPattern = "(&(objectclass=person)(|(uid={0})(mail={0})(cn={0})))"

More "|" terms increases search timeFT Index Domino Directory if term cannot be serviced by view search

DirGroups.m_GroupObjectClasses = {"groupOfNames"}Uses slightly more efficient LDAP compare instead LDAP searchUse {"groupOfUniqueNames"} when running against Netscape onlyUse {"groupOfNames", "groupOfUniqueNames"} when running against LDAP servers from various vendors

Domino 6 LDAP Query-Results CacheDomino 6.02 LDAP improves DirGroups.findMembers response for attributes with hundreds of valuesUse LDAPDEBUG=1 in Notes.ini to trace LDAP server

Domino LDAP Server Tips

Page 28: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

Client-side LDAP Improvements

Eliminate trips to LDAP server for duplicated group queriesfindMembers("cn=Iris Directory Team", ...)findGroups("cn=ken lin,ou=westford,o=ibm", ...)

Reduce trips to LDAP server for "similar" group queriesfindMembers("cn=Iris Directory Team", ...) vs.findMembers("cn=LDAP Server Dev', ...)findGroups("cn=ken lin,ou=westford,o=ibm") -> 104 groups vs.findGroups("cn=scott m davidson,ou=westford,o=ibm") -> 135 groups

Eliminate trips to LDAP server for duplicated name resolution queriesTBD - improve DirGroups.isGroup by consulting cached "objectclass=groupOfNames" results (FT Index)TBD - cache LDAP bind requests

Page 29: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

InitialDirContextCache

Extends javax.naming.InitialDirContextOverrides and caches DirContext's getAttributes and search

DirGroupsor other

JNDI calls

Initial-DirContext-

Cache

Initial DirContext

LDAP ServerApp

Internally, query-results caches are implemented via HashtablesName.compareTo() is important for Hashtable entry comparisonNot a single line of DirGroups or your JNDI calls was changed to take advantage of caching!

Page 30: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

InitialDirContextCache.getAttributespublic Attributes getAttributes(Name name, String[] attrIds) throws NamingException{

String key = toKey(name, attrIds);Object cached = m_AttributesCache.get(key);Attributes attrs = null;

if (cached == null) {try {

attrs = super.getAttributes(name, attrIds);if (attrs != null) {

Attributes value = (Attributes)attrs.clone();m_AttributesCache.put(key, value);

}} catch (NamingException e) {

m_AttributesCache.put(key, e.toString());throw e;

}} else {

if (cached instanceof String) {throw new NamingException(cached.toString());

} else {attrs = (Attributes)cached;

}}

return attrs;}

cache implemented via Hashtable

performs the real LDAP call

makes a 2-tuple from name/attrIDs

Page 31: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

Two and Three-Tier Architectures

Two-Tier Architecture

LDAPServer

JNDI orDirGroupsApp

JNDI orDirGroupsApp

JNDI orDirGroupsApp

JNDI orDirGroups

AppBack

AppFront

AppFront

AppFront

LDAPServer

Three-Tier Architecture

e.g., Domino DA, Sametime, J2EE, dgservlet

e.g., Mail clients

Page 32: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging & Collaboration

Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation

From Now To Next

ReviewTomorrowQuestions

Tidy Up

Page 33: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

Review

Algorithms and CodeLocate a Directory Server DirServer.getServers()Resolve and Authenticate a userDirUser.authenticate()Find a Group's Members DirGroups.findMembers()Find a Member's Groups DirGroups.findGroups()

Cache Query Results InitialDirContextCache

Improvements

Page 34: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

Tomorrow

Run nslookup, look for SRVsDownload seminar samplesRun DirServer.main()Run DirUser.main()Install and run dgservletTry "real" directoriesExperiment!

Page 35: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging and Collaboration

© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003

ReferencesCollaborative Cuisine's 1 Hour JNDI Cookbook - LSM 2003 https://www-914.ibm.com/events/lsm/03lsm.nsfBuilding Directory Friendly Applications - LSM 2002 https://www-914.ibm.com/events/lsm/02lsm.nsf/lookupwebpage/AbsPresAppDevJNDI Tutorial - Tips for LDAP Users http://java.sun.com/products/jndi/tutorial/ldap/index.html

Java Servlet Technology http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Servlets.htmlEclipse - an open extensible IDE http://eclipse.orgDirectory Services Markup Language http://www.oasis-open.org/cover/dsml.html

The String Representation of LDAP Search Filters http://www.ietf.org/rfc/rfc2254.txtA DNS RR for specifying the location of services (DNS SRV) http://www.ietf.org/rfc/rfc2782.txt http://www.ietf.org/internet-drafts/draft-ietf-ldapext-locate-08.txtA Summary of the X.500(96) User Schema for use with LDAPv3 http://www.ietf.org/rfc/rfc2256.txt

Misc.

LDAP

JNDI

Page 36: Collaborative Cuisine's 1 Hour JNDI Cookbook

Lotus Software - Messaging & Collaboration

Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation

From Now To Next

Questions?