Today, I would like to show you an example of a custom query to an LDAP, this query obtains a multi-valued LDAP attribute.
Situation
Imagine you need to know the associated user ids that are linked to an existing user, so you know the name of the LDAP attribute which is “associatedUserID”, and of course you have access to LDAP using a valid user and password.
1) Create a method to run a query to LDAP:
/* * An example of a method with a query to get a multi-valued attribute */ public boolean isUserAssociatedWithAUser(String userID, String associatedUserID){ DirContext context = null; String dn = ""; try { Hashtable env = new Hashtable(); env.put(Context.SECURITY_PRINCIPAL, "your_admin_id"); env.put(Context.SECURITY_CREDENTIALS, "password_admin"); DirContext initial = new InitialDirContext(env); context = (DirContext) initial.lookup("server_url"); String ou[] = {"department", "network"}; for(int i = 0;i < ou.length;i++) { String base = "userid=" + userID + ",ou=" + ou[i] + ",o=your_domain.com"; // Your custom LDAP query String filter = "(objectclass=*)"; // Your filter SearchControls sc = new SearchControls(); sc.setSearchScope(SearchControls.OBJECT_SCOPE); // Set scope of your search // The LDAP attribute that you are looking for, in this example "associatedUserID" is multi-valued sc.setReturningAttributes(new String[] {"associatedUserID"}); try { NamingEnumeration answer = context.search(base, filter, sc); dn = base; while (answer.hasMore()) { SearchResult sr = (SearchResult) answer.next(); Attributes attrs = sr.getAttributes(); List associatedUserIDs = getAssociatedUserIdsFromAttrs(attrs); for(int j=0; j<associatedUserIDs.size(); j++) { Object associatedPortalUserID = associatedUserIDs.get(j); if(associatedPortalUserID instanceof String) { String associatedPortalUserIDStr = (String)associatedPortalUserID; if(associatedPortalUserIDStr.indexOf(associatedUserID) >= 0) { dpLogger.info(userID + " is associated with " + associatedPortalUserIDStr); return true; } } } }// ends while } catch (javax.naming.NameNotFoundException e) { //Do nothing since the user is not in this ou } // Found if (! dn.equals("")){ break;} } } catch (javax.naming.CommunicationException e) { System.out.println("Admin Authentication Exception: Could not communicate with user directory."); return false; } catch(Exception e) { System.out.println("An Error occured while trying to Authenticate Admin."); return false; } finally { if ( context != null ) { try { context.close(); } catch (Exception e) {} } } //Check if the user ID was found if (dn.equals("")) { System.out.println("User not found error"); return false; } return false; }
2) For explaining purposes, I have split the reading operation (using a Attributes enumeration) in another method:
public List getAssociatedUserIdsFromAttrs(Attributes attrs) { List associatedUsers = new ArrayList(); if (attrs != null) { try { for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();) { Attribute attr = (Attribute) ae.next(); System.out.println("Attribute ID:" + attr.getID()); // Obtaining only the associatedUserID attribute's values if(attr.getID().equals("associatedUserID")) { NamingEnumeration e = attr.getAll(); while(e.hasMore()) { String value = e.next().toString(); System.out.println("Value: " + value); associatedUsers.add(value); } } } }catch (NamingException e) { e.printStackTrace(); } } return associatedUsers; }
That’s it!
Be happy with your code!