From deec025971bc0e33f40479a27fa3e9687673b95d Mon Sep 17 00:00:00 2001 From: Michael Miko Date: Fri, 29 Jul 2016 18:04:57 +0900 Subject: [PATCH 1/2] Add option to separate user search and user authentication --- .../marathon/plugin/auth/type/LDAPConfig.java | 16 ++++++ .../marathon/plugin/auth/util/LDAPHelper.java | 52 ++++++++++++++----- .../marathon/plugin/auth/plugin-conf.json | 2 + 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/main/java/io/containx/marathon/plugin/auth/type/LDAPConfig.java b/src/main/java/io/containx/marathon/plugin/auth/type/LDAPConfig.java index f71cc6b..4e9acf8 100644 --- a/src/main/java/io/containx/marathon/plugin/auth/type/LDAPConfig.java +++ b/src/main/java/io/containx/marathon/plugin/auth/type/LDAPConfig.java @@ -25,6 +25,12 @@ public class LDAPConfig { @JsonProperty(required = false) private String groupSubTree = "ou=Group"; + @JsonProperty(required = false) + private String bindUser = null; + + @JsonProperty(required = false) + private String bindPassword = null; + public LDAPConfig() {} @@ -44,6 +50,14 @@ public void setBase(String base) { this.base = base; } + public String getBindUser() { + return bindUser; + } + + public String getBindPassword() { + return bindPassword; + } + public String getDn() { return dn; } @@ -90,6 +104,8 @@ public String toString() { "url='" + url + '\'' + ", base='" + base + '\'' + ", dn='" + dn + '\'' + + ", bindUser='" + bindUser + '\'' + + ", bindPassword='" + bindPassword + '\'' + ", userSearch='" + userSearch + '\'' + ", userSubTree='" + userSubTree + '\'' + ", groupSearch='" + groupSearch + '\'' + diff --git a/src/main/java/io/containx/marathon/plugin/auth/util/LDAPHelper.java b/src/main/java/io/containx/marathon/plugin/auth/util/LDAPHelper.java index 7829408..2904471 100644 --- a/src/main/java/io/containx/marathon/plugin/auth/util/LDAPHelper.java +++ b/src/main/java/io/containx/marathon/plugin/auth/util/LDAPHelper.java @@ -20,7 +20,7 @@ public final class LDAPHelper { private static final Logger LOGGER = LoggerFactory.getLogger(LDAPHelper.class); - public static Set validate(String username, String password, LDAPConfig config ) { + public static Set validate(String username, String userPassword, LDAPConfig config) { if (config == null) { LOGGER.warn("LDAP Configuration not defined. Skipping LDAP authentication"); @@ -30,22 +30,31 @@ public static Set validate(String username, String password, LDAPConfig DirContext context = null; try { - String dn = new StringBuilder(config.getDn().replace("{username}", username)) - .append(",") - .append(config.getUserSubTree() != null ? config.getUserSubTree() + "," : "") - .append(config.getBase()) - .toString(); + String dn = ""; + String bindUser = config.getBindUser(); + String bindPassword = userPassword; + + if(bindUser != null) { + dn = bindUser; + bindPassword = config.getBindPassword(); + } else { + dn = new StringBuilder(config.getDn().replace("{username}", username)) + .append(",") + .append(config.getUserSubTree() != null ? config.getUserSubTree() + "," : "") + .append(config.getBase()) + .toString(); + } - LOGGER.debug("LDAP trying to connect as {} on {}", dn, config.getUrl()); + LOGGER.error("LDAP trying to connect as {} on {}", dn, config.getUrl()); Hashtable env = new Hashtable<>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, config.getUrl()); env.put(Context.SECURITY_PRINCIPAL, dn); - env.put(Context.SECURITY_CREDENTIALS, password); + env.put(Context.SECURITY_CREDENTIALS, bindPassword); context = new InitialDirContext(env); // if an exception wasn't raised, then we managed to bind to the directory - LOGGER.info("LDAP Auth succeeded for user {}", dn); + LOGGER.info("LDAP Bind succeeded for user {}", dn); SearchControls controls = new SearchControls(); controls.setSearchScope(SUBTREE_SCOPE); @@ -59,7 +68,7 @@ public static Set validate(String username, String password, LDAPConfig .append(",").append(searchContext) .toString(); } - LOGGER.debug("LDAP searching {} in {}", searchString, searchContext); + LOGGER.error("LDAP searching {} in {}", searchString, searchContext); NamingEnumeration renum = context.search(searchContext, searchString, controls); @@ -69,7 +78,24 @@ public static Set validate(String username, String password, LDAPConfig } SearchResult result = renum.next(); - LOGGER.debug("LDAP user search found {}", result.toString()); + LOGGER.error("LDAP user search found {}", result.toString()); + + if(bindUser != null) { + Attribute realDN = result.getAttributes().get("distinguishedname"); + dn = realDN.get(0).toString(); + + if(userPassword == null || userPassword.isEmpty()) { + return null; + } + + LOGGER.error("Authenticate with DN {}", dn); + env.put(Context.SECURITY_PRINCIPAL, dn); + env.put(Context.SECURITY_CREDENTIALS, userPassword); + + context = new InitialDirContext(env); + + LOGGER.info("LDAP Auth succeeded for user {}", dn); + } // search group memberships as user attributes Attribute memberOf = result.getAttributes().get("memberOf"); @@ -96,14 +122,14 @@ public static Set validate(String username, String password, LDAPConfig .append(",").append(searchContext) .toString(); } - LOGGER.debug("LDAP searching for group membership {} in {}", searchString, searchContext); + LOGGER.error("LDAP searching for group membership {} in {}", searchString, searchContext); renum = context.search(searchContext, searchString, controls); while (renum.hasMore()) { SearchResult group = renum.next(); String groupName = group.getAttributes().get("cn").get().toString(); memberships.add(groupName); - LOGGER.debug("LDAP found {} in group {}", username, groupName); + LOGGER.error("LDAP found {} in group {}", username, groupName); } } diff --git a/src/main/resources/io/containx/marathon/plugin/auth/plugin-conf.json b/src/main/resources/io/containx/marathon/plugin/auth/plugin-conf.json index ab3eb8a..813d345 100644 --- a/src/main/resources/io/containx/marathon/plugin/auth/plugin-conf.json +++ b/src/main/resources/io/containx/marathon/plugin/auth/plugin-conf.json @@ -12,6 +12,8 @@ "url": "ldap://my.ldapserver.local:389", "base": "dc=example,dc=com", "dn": "uid={username}", + "bindUser": "usernameToBind", + "bindPassword": "passwordToBind", "userSearch": "(&(uid={username})(objectClass=inetOrgPerson))", "userSubTree": "ou=People", "groupSearch": "(&(memberUid={username})(objectClass=posixGroup))", From e0bb2e46d7e5c7e2e5eba59302ecfed0ffdf0cf9 Mon Sep 17 00:00:00 2001 From: Michael Miko Date: Fri, 29 Jul 2016 18:07:15 +0900 Subject: [PATCH 2/2] Putting back logger --- .../marathon/plugin/auth/util/LDAPHelper.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/containx/marathon/plugin/auth/util/LDAPHelper.java b/src/main/java/io/containx/marathon/plugin/auth/util/LDAPHelper.java index 2904471..8519eed 100644 --- a/src/main/java/io/containx/marathon/plugin/auth/util/LDAPHelper.java +++ b/src/main/java/io/containx/marathon/plugin/auth/util/LDAPHelper.java @@ -45,7 +45,7 @@ public static Set validate(String username, String userPassword, LDAPCon .toString(); } - LOGGER.error("LDAP trying to connect as {} on {}", dn, config.getUrl()); + LOGGER.debug("LDAP trying to connect as {} on {}", dn, config.getUrl()); Hashtable env = new Hashtable<>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, config.getUrl()); @@ -68,7 +68,7 @@ public static Set validate(String username, String userPassword, LDAPCon .append(",").append(searchContext) .toString(); } - LOGGER.error("LDAP searching {} in {}", searchString, searchContext); + LOGGER.debug("LDAP searching {} in {}", searchString, searchContext); NamingEnumeration renum = context.search(searchContext, searchString, controls); @@ -78,7 +78,7 @@ public static Set validate(String username, String userPassword, LDAPCon } SearchResult result = renum.next(); - LOGGER.error("LDAP user search found {}", result.toString()); + LOGGER.debug("LDAP user search found {}", result.toString()); if(bindUser != null) { Attribute realDN = result.getAttributes().get("distinguishedname"); @@ -88,7 +88,7 @@ public static Set validate(String username, String userPassword, LDAPCon return null; } - LOGGER.error("Authenticate with DN {}", dn); + LOGGER.debug("Authenticate with DN {}", dn); env.put(Context.SECURITY_PRINCIPAL, dn); env.put(Context.SECURITY_CREDENTIALS, userPassword); @@ -122,14 +122,14 @@ public static Set validate(String username, String userPassword, LDAPCon .append(",").append(searchContext) .toString(); } - LOGGER.error("LDAP searching for group membership {} in {}", searchString, searchContext); + LOGGER.debug("LDAP searching for group membership {} in {}", searchString, searchContext); renum = context.search(searchContext, searchString, controls); while (renum.hasMore()) { SearchResult group = renum.next(); String groupName = group.getAttributes().get("cn").get().toString(); memberships.add(groupName); - LOGGER.error("LDAP found {} in group {}", username, groupName); + LOGGER.debug("LDAP found {} in group {}", username, groupName); } }