LDAP Authentication with Core Spring LDAP
1. Introduction to LDAP
LDAP (Lightweight Directory Access Protocol) is an open, industrial standard application protocol for reading and editing distributed directories over the network. These directories contain a set of records in an organized hierarchical structure, similar to how a corporate email directory looks like or a telephone directory which has an alphabetic list of persons with their address and phone numbers. LDAP enables anyone to locate resources in a network, be it on a public internet or corporate intranet.
Useful Links
2. LDAP test server details
Directory structure on the test LDAP server looks like:
Let’s check out the users who are Mathematicians –
3. Problem Statement
Based on the directory structure provided by the test LDAP server, in this post we will try to authenticate if the logged-in user is a member of a particular role AD group, which in our case would be ROLE_Mathematicians. Read more details on the test LDAP server here
4. Why LDAP authentication with Core Spring LDAP rather than what we did earlier with Spring Security?
No doubt, Spring Security provides us with the most standard and durable implementation to LDAP authentication, but with Core Spring LDAP, the approach becomes a bit ugly, yet gets better streamlined. The latter approach (with Core Spring LDAP) has been noticed to drastically improve the performance of your application when compared to that with Spring Security. Though it’s less advised to go with this approach, we still count it to be one of the alternative for improvement in the application’s performance.
5. Implementation
As for the implementation, below is the sample code how we could do it.
Read carefully through the comments as well in the below code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
public class SimpleLDAPClient { public static void main(String[] args) { /* LDAP Constants - must be placed in property files */ String base = "dc=example,dc=com"; // fetch username and password from HttpHeaders String dn = "uid="+username+","+base; String groupRoleAttribute = "cn"; String groupSearchBase = "dc=example,dc=com"; String groupToSearch = "ROLE_Mathematicians"; /* Configuring LDAP environment */ Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://ldap.forumsys.com:389/"); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, dn); env.put(Context.SECURITY_CREDENTIALS, "password"); InitialDirContext ctx = null; NamingEnumeration results = null; try { // initialize the context // successful initialization further means that the user has logged-in // successfully to the ldap server ctx = new InitialDirContext(env); // configure search controls SearchControls controls = new SearchControls(); controls.setSearchScope(SearchControls.SUBTREE_SCOPE); // prepare role group search string (cn=ROLE_Mathematicians), with the role AD group that needs to be searched SearchBuilder roleGroupSearchString = new StringBuilder(groupRoleAttribute); roleGroupSearchString.append("="); roleGroupSearchString.append(groupToSearch); // search role group ('Mathematicians') within the group base directory ('dc=example,dc=com') results = ctx.search(groupSearchBase, roleGroupSearchString, controls); // loop through the groups found as a result of search // only one group for 'Mathematicians' would be found in search // so the loop executes only once while (results.hasMore()) { SearchResult searchResult = (SearchResult) results.next(); Attributes attributes = searchResult.getAttributes(); // get all the uniqueMembers within the group 'Mathematicians' NamingEnumeration<String> allMembersInGroup = attributes.get("uniqueMember").getAll(); // loop though the uniqueMembers found within the group 'Mathematicians' while (allMembersInGroup.hasMore()) { String userString = (String) allMembersInGroup.next(); System.out.println(userString); // do string manipulations to get the user id, and match it with that of current logged-in user } } } catch (AuthenticationException e) { System.out.println("Authentication failed! Access denied."); // throw your own custom exception } catch (Exception e) { System.out.println("Some exception occured"); // throw your own custom exception } finally { if (results != null) { try { results.close(); } catch (Exception e) { } } if (ctx != null) { try { ctx.close(); } catch (Exception e) { } } } } } |
I believe this is something that you would find so clearly written elsewhere on the web. I am expecting to hear you thoughts to make this even better.