From 410fe722ee46c756771baec70869cbfe0f7f5eb5 Mon Sep 17 00:00:00 2001 From: Misagh Moayyed Date: Thu, 5 Jan 2017 12:51:56 +0330 Subject: [PATCH] Turned into boot --- .gitignore | 2 + README.md | 28 ++- Test.java | 184 ------------------ pom.xml | 41 ++++ src/main/java/net/unicon/Test.java | 167 ++++++++++++++++ .../main/resources/Test.properties | 14 +- src/main/resources/logback.xml | 20 ++ 7 files changed, 259 insertions(+), 197 deletions(-) delete mode 100644 Test.java create mode 100644 pom.xml create mode 100644 src/main/java/net/unicon/Test.java rename Test.properties => src/main/resources/Test.properties (55%) create mode 100644 src/main/resources/logback.xml diff --git a/.gitignore b/.gitignore index 6b468b6..171daff 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *.class +.idea +target diff --git a/README.md b/README.md index c48b4a3..9756e09 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,31 @@ -Java Keystore LDAPS Test +Java LDAP Test ==================== -##Configuration -See [`Test.properties`](https://github.com/mmoayyed/java-ldap-ssl-test/blob/master/Test.properties). +This is a small test utility that attempts to connect to an LDAP instance, +authenticate a given credential and retrieve attributes. It is very helpful +for testing secure connections, LDAPS and certificate configuration. -##Build -To compile and then use, execute: +## Configuration +See [`Test.properties`](https://github.com/mmoayyed/java-ldap-ssl-test/blob/master/src/main/resources/Test.properties). + +## Build + +```bash +mvn clean package ``` -javac Test.java -java Test + +## Usage + +- Download the JAR from [here](https://github.com/UniconLabs/java-ldap-ssl-test/releases) +- Run: + +``` +java -jar ``` ##Sample output + The log below demonstrates a sample of the program output configured to hit 5 ldap urls. ``` @@ -86,4 +99,3 @@ The log below demonstrates a sample of the program output configured to hit 5 ld [INFO] Ldap search completed successfully. ``` - diff --git a/Test.java b/Test.java deleted file mode 100644 index 7dbe4d7..0000000 --- a/Test.java +++ /dev/null @@ -1,184 +0,0 @@ -import java.io.IOException; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Properties; -import java.util.logging.ConsoleHandler; -import java.util.logging.Formatter; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -import javax.naming.Context; -import javax.naming.NamingEnumeration; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; -import javax.naming.directory.SearchControls; -import javax.naming.directory.SearchResult; - -public class Test extends Formatter { - private static final Logger theLogger = Logger.getLogger(Test.class.getName()); - - public static void main(final String[] args) throws IOException { - - final Properties props = new Properties(); - props.load(Test.class.getResourceAsStream("Test.properties")); - - try { - theLogger.setUseParentHandlers(false); - final ConsoleHandler handler = new ConsoleHandler(); - handler.setFormatter(new Test()); - theLogger.addHandler(handler); - - connect(props); - } catch(final IllegalArgumentException e) { - theLogger.severe(e.getMessage()); - } catch (final Exception e) { - theLogger.severe(e.getMessage()); - e.printStackTrace(); - } - } - - private static Pair getContext(final Properties props) { - for (int i = 0; i<5; i++) { - String ldapUrl = props.getProperty("ldap.url" + (i + 1)); - - if (ldapUrl != null && !ldapUrl.isEmpty()) { - ldapUrl = ldapUrl.trim(); - - final Hashtable env = new Hashtable(6); - env.put(Context.INITIAL_CONTEXT_FACTORY, props.getProperty("ldap.factory")); - env.put(Context.PROVIDER_URL, ldapUrl.trim()); - env.put(Context.SECURITY_AUTHENTICATION, props.getProperty("ldap.authentication")); - env.put(Context.SECURITY_PRINCIPAL, props.getProperty("ldap.userId")); - env.put(Context.SECURITY_CREDENTIALS, props.getProperty("ldap.password")); - env.put("com.sun.jndi.ldap.connect.timeout", props.getProperty("ldap.timeout")); - - printConfig(env); - try { - return new Pair(ldapUrl, new InitialDirContext(env)); - } catch (Exception e) { - theLogger.info("Failed to connect to ldap instance [" + ldapUrl.trim() + "]. Trying next...\n"); - } - } - } - return null; - } - - private static void connect(final Properties props) throws Exception { - final String[] attrIDs = props.getProperty("ldap.attributes").split(","); - - final SearchControls ctls = new SearchControls(); - ctls.setDerefLinkFlag(true); - ctls.setTimeLimit(new Integer(props.getProperty("ldap.timeout"))); - ctls.setReturningAttributes(attrIDs); - ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); - - final Pair pair = getContext(props); - if (pair == null) { - throw new IllegalArgumentException("Could not connect to any of the provided ldap urls based on the given credentials."); - } - - DirContext ctx = null; - - try { - ctx = pair.getSecond(); - - String log = "Successfully connected to the ldap url [" + pair.getFirst().trim() + "] "; - if (ctx.getNameInNamespace() != null && !ctx.getNameInNamespace().isEmpty()) { - log += "with namespace [" + ctx.getNameInNamespace() + "]."; - } - log += "\n"; - theLogger.info(log); - - theLogger.info("******* Ldap Search *******"); - theLogger.info("Ldap filter: " + props.getProperty("ldap.filter")); - theLogger.info("Ldap search base: " + props.getProperty("ldap.baseDn")); - theLogger.info("Returning attributes: " + Arrays.toString(attrIDs)); - theLogger.info("***************************\n"); - - final NamingEnumeration answer = ctx.search(props.getProperty("ldap.baseDn"), props.getProperty("ldap.filter"), ctls); - if (answer.hasMoreElements()) { - theLogger.info("******* Ldap Search Results *******"); - while (answer.hasMoreElements()) { - final SearchResult result = answer.nextElement(); - theLogger.info("User name: " + result.getName()); - theLogger.info("User full name: " + result.getNameInNamespace()); - - String authnPsw = props.getProperty("ldap.authn.password"); - if (authnPsw != null) { - theLogger.info("Attempting to authenticate " + result.getName() + " with password " + authnPsw); - - final Hashtable env = new Hashtable(6); - env.put(Context.INITIAL_CONTEXT_FACTORY, props.getProperty("ldap.factory")); - env.put(Context.PROVIDER_URL, pair.getFirst().trim()); - env.put(Context.SECURITY_AUTHENTICATION, props.getProperty("ldap.authentication")); - env.put(Context.SECURITY_PRINCIPAL, result.getNameInNamespace()); - env.put(Context.SECURITY_CREDENTIALS, authnPsw); - env.put("com.sun.jndi.ldap.connect.timeout", props.getProperty("ldap.timeout")); - DirContext userCtx = new InitialDirContext(env); - theLogger.info("Successfully authenticated " + result.getName() + " with password " + authnPsw + " at " + pair.getFirst()); - } - final NamingEnumeration attrs = result.getAttributes().getIDs(); - - while (attrs.hasMoreElements()) { - final String id = attrs.nextElement(); - theLogger.info(id + " => " + result.getAttributes().get(id)); - } - } - theLogger.info("************************************\n"); - } else { - theLogger.info("No search results could be found. \n"); - } - - theLogger.info("Ldap search completed successfully. \n"); - } finally { - if (ctx != null) - ctx.close(); - - } - } - - private static void printConfig(final Hashtable table) { - theLogger.info("******* Ldap Configuration *******"); - - final Enumeration names = table.keys(); - while (names.hasMoreElements()) { - final String str = names.nextElement(); - theLogger.info(str + ": " + table.get(str)); - } - theLogger.info("**********************************\n"); - } - - @Override - public String format(final LogRecord record) { - final StringBuffer sb = new StringBuffer(); - - sb.append("["); - sb.append(record.getLevel().getName()); - sb.append("]\t"); - - sb.append(formatMessage(record)); - sb.append("\n"); - - return sb.toString(); - } - - private static class Pair { - private F first; - private S second; - - public Pair(F f, S s) { - this.first = f; - this.second = s; - } - - public F getFirst() { - return this.first; - } - - public S getSecond() { - return this.second; - } - } - -} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..373ae44 --- /dev/null +++ b/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + net.unicon + java-ldap-keystore-test + 0.0.1 + Java LDAP Keystore Test Utility + jar + Java CLI utility to execute LDAP connections. + + + org.springframework.boot + spring-boot-starter + 1.4.3.RELEASE + + + + + + org.springframework.boot + spring-boot-maven-plugin + 1.4.3.RELEASE + + + + repackage + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + diff --git a/src/main/java/net/unicon/Test.java b/src/main/java/net/unicon/Test.java new file mode 100644 index 0000000..5e3b54e --- /dev/null +++ b/src/main/java/net/unicon/Test.java @@ -0,0 +1,167 @@ +package net.unicon; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; + +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Properties; + +public class Test implements CommandLineRunner { + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static void main(String[] args) throws Exception { + SpringApplication.run(Test.class, args); + } + + public void run(final String... args) throws Exception { + final Properties props = new Properties(); + props.load(Test.class.getResourceAsStream("/Test.properties")); + + try { + connect(props); + } catch (final IllegalArgumentException e) { + logger.error(e.getMessage()); + } catch (final Exception e) { + logger.error(e.getMessage()); + e.printStackTrace(); + } + } + + private Pair getContext(final Properties props) { + for (int i = 0; i < 5; i++) { + String ldapUrl = props.getProperty("ldap.url" + (i + 1)); + + if (ldapUrl != null && !ldapUrl.isEmpty()) { + logger.info("\nAttempting connect to LDAP instance #" + (i + 1) + ": [" + ldapUrl.trim() + "].\n"); + ldapUrl = ldapUrl.trim(); + final Hashtable env = new Hashtable<>(6); + env.put(Context.INITIAL_CONTEXT_FACTORY, props.getProperty("ldap.factory")); + env.put(Context.PROVIDER_URL, ldapUrl.trim()); + env.put(Context.SECURITY_AUTHENTICATION, props.getProperty("ldap.authentication")); + env.put(Context.SECURITY_PRINCIPAL, props.getProperty("ldap.userId")); + env.put(Context.SECURITY_CREDENTIALS, props.getProperty("ldap.password")); + env.put("com.sun.jndi.ldap.connect.timeout", props.getProperty("ldap.timeout")); + + printConfig(env); + try { + return new Pair<>(ldapUrl, new InitialDirContext(env)); + } catch (Exception e) { + logger.info("\nFailed to connect to ldap instance #" + (i + 1) + ": [" + ldapUrl.trim() + "].\n"); + } + } + } + return null; + } + + private void connect(final Properties props) throws Exception { + final String[] attrIDs = props.getProperty("ldap.attributes").split(","); + + final SearchControls ctls = new SearchControls(); + ctls.setDerefLinkFlag(true); + ctls.setTimeLimit(new Integer(props.getProperty("ldap.timeout"))); + ctls.setReturningAttributes(attrIDs); + ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + final Pair pair = getContext(props); + if (pair == null) { + throw new IllegalArgumentException("\nCould not connect to any of the provided LDAP urls based on the given credentials."); + } + + DirContext ctx = null; + + try { + ctx = pair.getSecond(); + + String log = "Successfully connected to the LDAP url [" + pair.getFirst().trim() + "] "; + if (ctx.getNameInNamespace() != null && !ctx.getNameInNamespace().isEmpty()) { + log += "with namespace [" + ctx.getNameInNamespace() + "]."; + } + log += "\n"; + logger.info(log); + + logger.info("******* Ldap Search *******"); + logger.info("Ldap filter: " + props.getProperty("ldap.filter")); + logger.info("Ldap search base: " + props.getProperty("ldap.baseDn")); + logger.info("Returning attributes: " + Arrays.toString(attrIDs)); + logger.info("***************************\n"); + + final NamingEnumeration answer = ctx.search(props.getProperty("ldap.baseDn"), props.getProperty("ldap.filter"), ctls); + if (answer.hasMoreElements()) { + logger.info("******* Ldap Search Results *******"); + while (answer.hasMoreElements()) { + final SearchResult result = answer.nextElement(); + logger.info("User name: " + result.getName()); + logger.info("User full name: " + result.getNameInNamespace()); + + String authnPsw = props.getProperty("ldap.authn.password"); + if (authnPsw != null) { + logger.info("Attempting to authenticate " + result.getName() + " with password " + authnPsw); + + final Hashtable env = new Hashtable<>(6); + env.put(Context.INITIAL_CONTEXT_FACTORY, props.getProperty("ldap.factory")); + env.put(Context.PROVIDER_URL, pair.getFirst().trim()); + env.put(Context.SECURITY_AUTHENTICATION, props.getProperty("ldap.authentication")); + env.put(Context.SECURITY_PRINCIPAL, result.getNameInNamespace()); + env.put(Context.SECURITY_CREDENTIALS, authnPsw); + env.put("com.sun.jndi.ldap.connect.timeout", props.getProperty("ldap.timeout")); + new InitialDirContext(env); + logger.info("Successfully authenticated " + result.getName() + " with password " + authnPsw + " at " + pair.getFirst()); + } + final NamingEnumeration attrs = result.getAttributes().getIDs(); + + while (attrs.hasMoreElements()) { + final String id = attrs.nextElement(); + logger.info(id + " => " + result.getAttributes().get(id)); + } + } + logger.info("************************************\n"); + } else { + logger.info("No search results could be found. \n"); + } + + logger.info("Ldap search completed successfully. \n"); + } finally { + if (ctx != null) + ctx.close(); + + } + } + + private void printConfig(final Hashtable table) { + logger.info("******* LDAP Instance Configuration *******"); + final Enumeration names = table.keys(); + while (names.hasMoreElements()) { + final String str = names.nextElement(); + logger.info(str + ": " + table.get(str)); + } + logger.info("********************************************\n"); + } + + private static class Pair { + private F first; + private S second; + + public Pair(F f, S s) { + this.first = f; + this.second = s; + } + + public F getFirst() { + return this.first; + } + + public S getSecond() { + return this.second; + } + } +} diff --git a/Test.properties b/src/main/resources/Test.properties similarity index 55% rename from Test.properties rename to src/main/resources/Test.properties index 52f254c..98c1ad3 100644 --- a/Test.properties +++ b/src/main/resources/Test.properties @@ -4,17 +4,21 @@ ldap.url3 = ldap.url4 = ldap.url5 = -#Bind credentials +# Bind credentials ldap.userId = casadmin@org.edu ldap.password = somePassword! +# The baseDn to start the search for accounts. ldap.baseDn = OU=some,DC=org,DC=edu -ldap.filter = (&(objectClass=*) (sAMAccountName=casadmin)) +# Search for a given LDAP account +# Authenticate via the provided password +# Retrieve attributes for the account. +ldap.filter = (&(objectClass=*) (sAMAccountName=casadmin)) +ldap.authn.password = password! ldap.attributes = cn,givenName +# Do not modify, unless you know what you're doing. ldap.factory = com.sun.jndi.ldap.LdapCtxFactory ldap.authentication = simple -ldap.timeout = 3000 - -ldap.authn.password = password! \ No newline at end of file +ldap.timeout = 5000 diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..300f678 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,20 @@ + + + + + + + %msg%n + + + + + + + + + + + + +