Today It's very common in most of the companies to have Microsoft Active Directory and Lotus Notes implementation together. We also use Active Directory and Lotus Notes side by side to validate Lotus Notes and SharePoint applications. Recently I've got a requirement to query Active Directory based on users profile which resides in our Lotus Notes view. I've implemented two sets of code one using Domino Java and jndi and other using Lotus Script. I've written Lotus script to those who are good in Lotus scripting and willing to perform such kind of cross implementation.By seeing the code you may realize how simple is to query Active directory from Domino using Lotus Scripting.To see the Lotus Script code , you may need to wait until it get published in Search Domino since it's already in process.So let's talk about Domino Java+JNDI.

In order to implement this code , You must need to know your Active Directory server name ( or IP address ) and make sure the port number where server is listening.

This code can be further extended to synchronized Lotus Notes address book contents in Active Directory or vice versa . Even it can be used to build Lotus Notes application which can use Active Directory for authentication.

To accomplish this, I'm using JNDI ( The Java Naming and Directory Interface ) which is an API specified in Java technology that provides naming and directory functionality to applications written in the Java programming language. It is designed especially for the Java platform using Java's object model. Using JNDI, applications based on Java technology can store and retrieve named Java objects of any type. In addition, JNDI provides methods for performing standard directory operations, such as associating attributes with objects and searching for objects using their attributes.

To start with the code ,

Step one: Include JNDI API package in your domino Java agent,


import javax.naming.*;


Step two:
JNDI applications need a way to communicate various preferences and information that define the environment in which naming and directory services are accessed.The following code creates an environment consisting of two security-related properties and creates an initial context using that environment.


Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
//Replace with actual server name and port number
env.put(Context.PROVIDER_URL, "ldap://serverName:389");
env.put(Context.SECURITY_PRINCIPAL, "CN=Rishi Sahi/OU=Development/O=Home");
env.put(Context.SECURITY_CREDENTIALS, "Password goes here");
DirContext ctx = new InitialDirContext(env);



Step 3: Build a search scope , You need to define Active directory attributes which are going to be searched,


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



In above code , SearchControls class encapsulates factors that determine scope of search and what gets returned as a result of the search.Next,setReturningAttributes() method specifies the attributes that will be returned as part of the search and setSearchScope() to SUBTREE_SCOPE to search the entire subtree rooted at the named object.

Step 4: Using search method of DirContext.It searches in a single context for objects that contain a specified set of attributes, and retrieves selected attributes. Note that my first argument is blank which make it search in entire scope, you can even define specific root.At the end make sure your results stored in NamingEnumeration type object.


String filter = "cn="+ searchUser;
NamingEnumeration answer = ctx.search("", filter,ctls);



Step 5: In the last step only you need to loop through your search results and retrieve attributes value.


while (answer.hasMore())
{
SearchResult sr = (SearchResult)answer.next();
System.out.println("<<" + sr.getName()+">>");
Attributes attrs = sr.getAttributes();
System.out.println(attrs.get("cn").get());
isFound="1";
}


Here is the complete code,



import javax.naming.*;
import javax.naming.directory.*;
import java.util.*;

public class LDAPQuery {

public static void ldapconnect(){

String searchUser="Rishi Sahi";
String isFound="0";

try {

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://serverName:389"); //Replace with actual server name and port number
env.put(Context.SECURITY_PRINCIPAL, "CN=Rishi Sahi/OU=Development/O=Home");
env.put(Context.SECURITY_CREDENTIALS, "Password goes here");
// Create initial context
DirContext ctx = new InitialDirContext(env);
// Specify the ids of the attributes to return
String[] attrIDs = {"cn","uid"};
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(attrIDs);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter = "cn="+ searchUser;
// Search for objects that have those matching attributes
NamingEnumeration answer = ctx.search("", filter,ctls);
try {
while (answer.hasMore())
{
SearchResult sr = (SearchResult)answer.next();
System.out.println("<<" + sr.getName()+">>");
Attributes attrs = sr.getAttributes();
System.out.println(attrs.get("cn").get());
isFound="1";
}

if ( isFound=="1") {
System.out.println("User found in Active Directory!");
} else {
System.out.println("Opps ! User not found in Active Directory!");
}
answer.close();
}catch(PartialResultException e) {
e.printStackTrace();
}
// Close the context when we're done
ctx.close();
} catch (Exception e) {
e.printStackTrace();
}

}

public LDAPQuery() {
// Don't think I'm doing anything here
}
}



To call this routine,


import lotus.domino.*;

public class JavaAgent extends AgentBase {

public void NotesMain() {

try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
LDAPQuery objQuery = new LDAPQuery();
objQuery.ldapconnect();
} catch(Exception e) {e.printStackTrace();}
}
}



Reference : Java Naming and Directory Interface

So thought of the day

"I love Lotus Notes because I don't see anything which is not possible in Domino."

4 Responses to "LDAP programming using Domino Java - Step by Step"

  1. gravatar sean Says:

    Thanks for this Rishi, I have searched high and low and this is one of the most useful resources I have found.

    Do you have any further hints about how to synchronise directories -0 I am not worried about passwords but I would like to extract all of the user names and emails from AD into a Notes database

    Thanks, Sean

  2. gravatar sean Says:

    p.s. LS would be preferable over Java but either would do ( I need to get better at Java in any case ! )

  3. gravatar Rainer Says:

    Dear Rishi,

    great code... Like sean said, it would be perfect if you also could post the code to save the persons from the AD into a Notes database

  4. gravatar sean Says:

    Here is the Search Domino URL http://searchdomino.techtarget.com/tip/Search-Microsoft-Active-Directory-with-LotusScript

Leave a Reply

preload preload preload