Integrating Active Directory from Java
Firstly you will need to setup Active Directory so that you can run and test your code.
If (like me) you don’t have a machine with Windows Server no worries, this is how you can set up Active Directory even on Mac OSX.
The first thing you want to do is set up a user a in AD. Make sure that when you set up the user he doesn’t have to change his password on the first login or you will get an LDAP error from your Java code.
Clearly you can change your code to prompt a password change but just something to be aware of.
Also create a couple of groups for your user and add them to their profile.
In the code below there is just one method, authenticate. It that takes as parameters a user, password and domain and returns a list of groups of which the user is a member. If the user does not exist or there is a problem with the password an exception is thrown.
package util; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.*; import java.text.MessageFormat; import java.util.*; public class ADConnect { private static final String MEMBER_OF = "memberOf"; public static List<String> authenticate(String user, String securityToken, String domain) throws NamingException { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "LDAP://" + domain); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, user + "@" + domain); env.put(Context.SECURITY_CREDENTIALS, securityToken); InitialDirContext ctx = new InitialDirContext(env); String[] dcParts = domain.split("\\."); String domainSearch = ""; for (String dcPart : dcParts) { domainSearch += "DC=" + dcPart + ","; } domainSearch = domainSearch.substring(0, domainSearch.length() - 1); // Create the search controls SearchControls searchCtls = new SearchControls(); String[] attributes = new String[]{MEMBER_OF}; searchCtls.setReturningAttributes(attributes); // Specify the search scope searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Search for objects using the filter NamingEnumeration result = ctx.search(domainSearch, MessageFormat.format("(SAMAccountName={0})", user), searchCtls); //Get the first result SearchResult sr = (SearchResult) result.next(); Attribute memberOf = sr.getAttributes().get(MEMBER_OF); List<String> memberOfGroups = new ArrayList<>(); if (memberOf != null) { for (Enumeration e1 = memberOf.getAll(); e1.hasMoreElements(); ) { memberOfGroups.add(e1.nextElement().toString()); } } return memberOfGroups; } public static void main(String[] args) throws NamingException{ System.out.println(ADConnect.authenticate("user", "password", "domain")); } }
The code is fairly self explanatory and you can use it as a template to experiment with adding different attributes to the search.
Reference: | Integrating Active Directory from Java from our JCG partner Daniel Shaya at the Rational Java blog. |
Hi Daniel,
Do you know what changes do I have to implement in order to find multiple users, or all users ?
Thank you,