LDAP Search and Pagination in java

Example API to search and paginate the result from your Microsoft LDAP server.

 

 

package ldap;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;
import java.util.logging.*;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.PagedResultsControl;
import javax.naming.ldap.PagedResultsResponseControl;

public class LDAPSearch {
	private static Logger log = Logger.getLogger(LDAPSearch.class.getSimpleName());
	private static LdapContext connection;
    private String host;
    private String user;
    private String password;
    private String basedIn;
    private String filter;
    private int pageSize;
    private String[] attributes;
    
    private boolean breakStop = false;
    private int breakCount = -1;
    
    private void setBreakCount(int count){
    	this.breakCount = count;
    }
    
    private void setBreakStop(boolean value){
    	this.breakStop = value;
    }
    
    private static LDAPSearch instance;
    
    private static LDAPSearch instance(String host, String user, String password, String basedIn,String filter, int pageSize, String... attributes) {
          if (instance == null){
        	  instance = new LDAPSearch(host, user, password, basedIn,filter, pageSize, attributes);
          }	
          return instance;
    }
    
    private LDAPSearch(String host, String user, String password, String basedIn,String filter, int pageSize, String... attributes) {
    	this.host     = host;
    	this.user     = user;
    	this.password = password;
    	this.basedIn  = basedIn;
    	this.filter   = filter;
    	this.pageSize = pageSize;
    	this.attributes = attributes;
    }
	
    public static AttributeIDValue[] search (String host, String user, String password, String basedIn,String filter, int pageSize, String... attrNames) {
    	LDAPSearch ldap = instance(host, user, password, basedIn,filter, pageSize, attrNames);
    	return ldap.search();
    }
    
    private AttributeIDValue[] search(){
    	List<AttributeIDValue> rs = new ArrayList<AttributeIDValue>();
    	LdapContext ctx   = null;
    	try{
    		 if(this.attributes == null || this.attributes.length == 0)
    			 throw new RuntimeException("What attributes are you trying to retrieve?");
    		 
    		 ctx = connection();
    		 SearchControls searchCtls = new SearchControls();
    		 searchCtls.setReturningAttributes(this.attributes);
             searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
             
             ctx.setRequestControls(new Control[]{new PagedResultsControl(this.pageSize,true)});
             
             
             byte[] cookie = null;
            
             int totalResults = 0;  
             
             
             do{
            	 NamingEnumeration<SearchResult> results = ctx.search(this.basedIn, this.filter, searchCtls);
            	 while (results != null && results.hasMoreElements()) {
            		    SearchResult sr = results.next();
            		    log.info("Search Result  Name : " + sr.getName());
            		    Attributes atts  = sr.getAttributes();
            		    NamingEnumeration<? extends Attribute> attsEnumerations = atts.getAll();
            		    while(attsEnumerations!= null && attsEnumerations.hasMoreElements()){
            		    	Attribute att = attsEnumerations.next();
            		    	AttributeIDValue attributeIDValue = new AttributeIDValue();
            		    	attributeIDValue.setKey(att.getID());
            		    	attributeIDValue.setValue(att.get());
            		    	log.info("Attribute  ID : "+att.getID()  + "  Attribute Value : " +att.get());
            		    	rs.add(attributeIDValue);
            		    }
            		 
            		 totalResults++; 
            	 }
            	
                 cookie = parseControls(ctx.getResponseControls());

                
                 ctx.setRequestControls(new Control[]{new PagedResultsControl(pageSize, cookie, Control.CRITICAL) });
                 
                 if(breakStop && breakCount != -1) {
                	 if(breakCount == totalResults){ break;}
                 }
             }while((cookie != null) && (cookie.length != 0));
             
             log.info("Total record retrieved for search : " + totalResults);
    		
    	} catch (NamingException | IOException e) {
    		log.severe(e.getMessage());
			e.printStackTrace();
		}finally{
    		if(ctx != null){
    			try {
					ctx.close();
				} catch (NamingException e) {
					log.severe(e.getMessage());
					e.printStackTrace();
				}
    		}
    	}
    	
    	
    	return rs.toArray(new AttributeIDValue[rs.size()]);
    }
    
    
    private LdapContext connection() throws NamingException {
    	if(connection == null){
    		Hashtable<String, String> env = new Hashtable<>();
    		env.put(Context.INITIAL_CONTEXT_FACTORY, properties().getProperty("ldap.factories.initctx"));
    		env.put(Context.PROVIDER_URL,this.host);
    		env.put(Context.SECURITY_AUTHENTICATION, "simple");
    		env.put(Context.SECURITY_PRINCIPAL, this.user);
    		env.put(Context.SECURITY_CREDENTIALS, this.password);
    		connection = new InitialLdapContext(env,null);
    	}
    	return connection;
    }
    
    
    
	public static void main(String[] args) {
		LDAPSearch ldap = instance(properties().getProperty("ldap.host"),
				                    properties().getProperty("ldap.user"), 
				                    properties().getProperty("ldap.password"), 
				                    properties().getProperty("ldap.basedIn"),
				                    properties().getProperty("ldap.filter"), 
				                    Integer.parseInt(properties().getProperty("ldap.pageSize")),
				                    "sn","givenName","mail");
		//ldap.setBreakCount(2000);
		//ldap.setBreakStop(true);
		ldap.search();
	}
	
	
	
	private static Properties props;
	static Properties properties() {
		if(props == null){
			props = new Properties();
			try {
				props.load(LDAPSearch.class.getResourceAsStream("ldap.properties"));
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
		return props;
	}
	
	
	private static byte[] parseControls(Control[] controls) throws NamingException {

		byte[] cookie = null;

		if (controls != null) {

			for (int i = 0; i < controls.length; i++) {
				if (controls[i] instanceof PagedResultsResponseControl) {
					PagedResultsResponseControl prrc = (PagedResultsResponseControl) controls[i];

					cookie = prrc.getCookie();

					System.out.println(">>Next Page \n");

				}

			}

		}

		return (cookie == null) ? new byte[0] : cookie;

	}
}

 

 

 

# LDAP parameters 
ldap.host =ldap://ldap.server.com:389
ldap.factories.initctx =com.sun.jndi.ldap.LdapCtxFactory 
ldap.basedIn = DC=corp,DC=server,DC=com 
ldap.user=domain\\userName 
ldap.filter=(&(objectClass=user)(mail=*)) 
ldap.password=password 
ldap.pageSize=1000

 

 

package ldap;

public class AttributeIDValue {
	
	private String key;
	private Object value;
	
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public Object getValue() {
		return value;
	}
	public void setValue(Object value) {
		this.value = value;
	}
	
	

}

 

 

Source for SearchLDAP