Many companies are using their corporate LDAP directory to store or to reference the employees’ photo:
- Some organizations are using a binary LDAP attribute (like the jpegPhoto attribute) to store directly the employee’s photo.
- Other organizations are using a text LDAP attribute (like the photoURL attribute ) to store the HTTP url where we can find the employee’s photo.
This article presents a sample of a service that retrieves the user’s photo from an LDAP directory, to display it in the Quickr (Domino Services) business card.
The service is delivered by a servlet named userphoto :
- The userphoto servlet uses an input XML file, named LDAPConfig.xml , for initializing several variables of the servlet.The path of the LDAPConfig.xml file is passed to the servlet as a servlet init argument. (In this article, we assume that the servlet is executed by the Domino servlet engine of the Quickr server. The domino server hosting Quickr must be configured to use this servlet engine)
- The userphoto servlet performs an LDAP search request to retrieve and return the user’s photo
- Then, the Quickr (domino services) qpconfig.xml file is customized to call the servlet in order to display the user’s photo into the the quickr business card
How to install this service on a quickr (Domino services) server
Step 1: Update the domino servlets.properties file
To update the servlets.properties file, follow these steps:
- With your favorite text editor, open the servlets.properties file of your Quickr (Domino services) server.
- Add one line as shown in Figure 1.
- Save the servlets.properties file
Remarks:
- The servlets.properties file is located into the domino \data\ directory of the quickr server.
- The myPath init argument value must match the configuration of your environment .
Figure 1. Updating the servlets properties file
|
servlet.QuickrSupportUtil.code=com.lotus.quickplace.util.QuickrSupportUtil
servlet.QuickrEntry.code=com.lotus.quickplace.util.QuickrEntry
servlet.QPServlet.code=com.lotus.quickplace.util.QPServlet
servlet.userphoto.initArgs= myPath=C:\\Domqr81\\data\\domino\\servlet\\ |
Step 2 : Create an LDAPconfig.xml file
To create the LDAPconfig.xml file, follow these steps:
- Open your favorite text editor and create a LDAPConfig.xml as shown in Figure 2.
- Save the file into the directory specified into the myPath init argument of the userphoto servlet (cf. Step1)
Remarks:
- Values of the LDAPConfig.xml file must match the configuration of your environment. The meaning of each parameter of the LDAPconfig.xml file is detailed below figure 2.
Figure 2. Creating the LDPAConfing.xml file

Let's clarify the meaning of each parameter of the LDAPconfig.xml file
- photoAttibute. The LDAP attribute to read to retrieve the user’s photo.
- photoValue. To specify if the LDAP attribute is a binary attribute containing directly the user’s photo or a text attribute containing an HTTP url for the user’s photo. The value of this parameter must be set either to binary or to link
- ldapServer. The DNS name of the LDAP server.
- ldapPort. The TCP port used by the LDAP server.
- ldapAuth. The authentication method to the LDAP server. The servlet described in this article supports only the simple authentication method.
- ldapPrincipal. The distinguished name of the LDAP person object to perform the LDAP Bind operation (required if the LDAP rights do not allow to read the attribute specified in the photoAttribute parameter, with an anonymous bind). If no value specified for this parameter, the servlet will perform an anonymous LDAP bind
- ldapCredentials. The LDAP password associated to the person object used to perform the LDAP Bind operation.
- SearchFilterAttribute. The LDAP attribute used to build the left side of the LDAP filter for the LDAP search request
- getParameterValue. The parameter to read into the http query string in order to get the value to be used in the right side of the LDAP filter for the LDAP search request.
- noEntryJpg. The url of an image to display when the LDAP search request does not return any LDAP entry
- noPhotoJpg. The url of an image to display when the LDAP search request returns an entry with no value for the attribute specified in the photoAttribute parameter
- consoleTrace. The purpose if this parameter is for troubleshooting only. If consoleTrace is set to on, values of the servlet’s variables are printed to the domino console.
Step 3 : Copy the userphoto.class file into the domino servlet directory
To execute this operation, follow these steps:
- Copy the userphoto.class file into into the domino \data\domino\servlet\ directory of the quickr server.
Remarks:
- The userphoto.class file is attached to this article
Step 4 : Post on a Web server images to display when the LDAP request is unable to retrieve the user’s photo.
To execute this operation, follow these steps:
- Select an image to display when the LDAP search request does not return any LDAP entry and post it on a web server
- Select an image to display when the LDAP search request returns an entry with no value for the attribute specifie d in the photoAttribute parameter.
Remarks:
- The url of these images must match the noEntryJpg and noPhotoJpg values of the LDAPConfig.xml file
Step 5: update the quickr qpconfig.xml file
To update the qpconfig file, follow these steps:
- With your favorite text editor, open the qpconfig.xml file of your Quickr (Domino services) server.
- Locate the user_photo_source element (a child of the user_directory element) and update it as shown in figure 3.
- LDAPConfig.xml
- Save the qpconfig.xml file
- Restart the HTTP task on the quickr (Domino services) server
Remarks:
- The qpconfig.xml file is located into the domino \data\ directory of the quickr server.
- With the example shown in figure 3, we assume that the mail value is used for both SearchFilterAttrib ute and getParameterValue into LDAPConfig.xml
Figure 3. Updating the qpconfig.xml file
Screen shots about utilization of this service
Call of the service directly from a browser

Display of the user’s photo into the Quickr business card (example with the photo stored into the jpegPhoto binary LDAP attribute)

The userphoto servlet source code (userphoto.java)
import java.util.*; import java.io.*;
import javax.naming.*; import javax.naming.directory.*; import javax.servlet.*; import javax.servlet.http.*; import org.w3c.dom.*;
import java.io.File; import javax.xml.parsers.*;
public class userphoto extends HttpServlet {
private static final long serialVersionUID = 4986088540795722497L;
public void doGet (final HttpServletRequest request, final HttpServletResponse response) throws IOException {
define and init variables with default values
final ServletOutputStream out = response.getOutputStream(); String getparam="mail"; String searchfilterattr="mail"; String photoattribute = "jpegphoto"; String photovalue = "binary"; String ldapserver = "localhost"; String ldapport = "389"; String ldapauth = "simple"; String ldapprincipal = ""; With empty values for ldapprincipal and ldapcredentials, String ldapcredentials = ""; an anonymous LDAP bind xill be peformed String getparamvalue=""; String noentryjpg=""; String nophotojpg=""; String consoletrace="off"; String ldapuri=""; String filter=""; Element element; NodeList nodeElementList;
Parse the LDAPConfig.xml file
try { String myPath = getServletConfig().getInitParameter("myPath"); File file = new File(myPath+"LDAPConfig.xml"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(file); doc.getDocumentElement().normalize(); NodeList list = doc.getElementsByTagName("config"); for (int i = 0; i < list.getLength(); i++) { Node node1 = list.item(i); if (node1.getNodeType() == Node.ELEMENT_NODE) { element = (Element) node1; nodeElementList = element.getElementsByTagName("photoAttibute"); photoattribute = ((Node) (((Element) nodeElementList.item(0)).getChildNodes()).item(0)).getNodeValue(); nodeElementList = element.getElementsByTagName("photoValue"); photovalue = ((Node) (((Element) nodeElementList.item(0)).getChildNodes()).item(0)).getNodeValue(); nodeElementList = element.getElementsByTagName("ldapServer"); ldapserver = ((Node) (((Element) nodeElementList.item(0)).getChildNodes()).item(0)).getNodeValue(); nodeElementList = element.getElementsByTagName("ldapPort"); ldapport = ((Node) (((Element) nodeElementList.item(0)) .getChildNodes()).item(0)).getNodeValue(); nodeElementList = element.getElementsByTagName("ldapAuth"); ldapauth = ((Node) (((Element) nodeElementList.item(0)).getChildNodes()).item(0)).getNodeValue(); nodeElementList = element.getElementsByTagName("ldapPrincipal"); ldapprincipal = ((Node) (((Element) nodeElementList.item(0)).getChildNodes()).item(0)).getNodeValue(); nodeElementList = element.getElementsByTagName("ldapCredentials"); ldapcredentials = ((Node) (((Element) nodeElementList.item(0)).getChildNodes()).item(0)).getNodeValue(); nodeElementList = element.getElementsByTagName("SearchFilterAttribute"); searchfilterattr = ((Node) (((Element) nodeElementList.item(0)).getChildNodes()).item(0)).getNodeValue(); nodeElementList = element.getElementsByTagName("getParameterValue"); getparam = ((Node) (((Element) nodeElementList.item(0)).getChildNodes()).item(0)).getNodeValue(); nodeElementList = element.getElementsByTagName("noEntryJpg"); noentryjpg = ((Node) (((Element) nodeElementList.item(0)).getChildNodes()).item(0)).getNodeValue(); nodeE
lementList = element.getElementsByTagName("noPhotoJpg"); nophotojpg = ((Node) (((Element) nodeElementList.item(0)).getChildNodes()).item(0)).getNodeValue(); nodeElementList = element.getElementsByTagName("consoleTrace"); consoletrace = ((Node) (((Element) nodeEle mentList.item(0)).getChildNodes()).item(0)).getNodeValue(); }if } for } catch (Exception e) {}
assign variable values
getparamvalue = request.getParameter(getparam); filter = "("+searchfilterattr+"=" + getparamvalue + ")"; ldapuri= "ldap:" + ldapserver + ":" + ldapport;
Print variable values to the system console if consoletrace=on
if ( consoletrace.equalsIgnoreCase( "on" ) ) { System.out.println("getparam :" + getparam); System.out.println("getparamvalue :" + getparamvalue); System.out.println("searchfilterattr :" + searchfilterattr); System.out.println("filter :" + filter); System.out.println("photoattribute :" + photoattribute); System.out.println("photovalue :" + photovalue); System.out.println("ldapserver :" + ldapserver); System.out.println("ldapport :" + ldapport); System.out.println("ldapuri :" + ldapuri); System.out.println("ldapauth :" + ldapauth); System.out.println("ldapprincipal :" + ldapprincipal); System.out.println("ldapcredentials :" + ldapcredentials); System.out.println("noentryjpg :" + noentryjpg); System.out.println("nophotojpg :" + nophotojpg); }
Perform the LDAP search request to read the LDAP attribute containing the user's photo. Then print the output or perform an HTTP redirection to send the user’s photo
try { final Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, ldapuri); env.put(Context.SECURITY_AUTHENTICATION,ldapauth); env.put(Context.SECURITY_PRINCIPAL,ldapprincipal); specify the username env.put(Cont ext.SECURITY_CREDENTIALS,ldapcredentials); specify the password final DirContext ctx = new InitialDirContext(env);
final SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); neede d
final String[] attrIDs = {photoattribute};
ctls.setReturningAttributes(attrIDs); final NamingEnumeration answer = ctx.search("", filter, ctls); int nbRes = 0; if (!(answer != null && answer.hasMore() )) { response.sendRedirect(noentryjpg); }
while (answer != null && answer.hasMore() && nbRes < 1) { nbRes++; final SearchResult sr = (SearchResult)answer.next(); final Attributes attrs = sr.getAttributes(); if (attrs == null) { response.sendRedirect(nophotojpg); } else { if ( attrs.get(photoattribute) != null) { if ( photovalue.equalsIgnoreCase( "link" ) ) { response.sendRedirect(( String )attrs.get(photoattribute).get(0)); } else { response.setContentType("image/jpeg"); out.write((byte[])attrs.get(photoattribute).get(0)); photo out.flush(); out.close(); } }if else { response.sendRedirect(nophotojpg); } else }else } while
ctx.close(); try catch (final Exception e) { e.printStackTrace(); } } doGetend }
| |