
com.hfg.ldap.LDAPClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
package com.hfg.ldap;
import java.lang.reflect.Method;
import java.util.*;
import java.util.logging.Logger;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.InvalidNameException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapName;
import com.hfg.exception.InvalidValueException;
import com.hfg.ldap.ad.ActiveDirectory;
import com.hfg.security.LoginCredentials;
import com.hfg.util.StringUtil;
import com.hfg.util.collection.CollectionUtil;
//------------------------------------------------------------------------------
/**
Simple LDAP Client.
@author J. Alex Taylor, hairyfatguy.com
*/
//------------------------------------------------------------------------------
// com.hfg XML/HTML Coding Library
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------
public class LDAPClient
{
private String mLDAP_ServerURL;
private LdapName mLDAP_UserContext;
private LdapName mLDAP_GroupContext;
private String mLDAP_PrincipalFieldName = "uid";
private LdapName mLDAP_PrincipalContext;
private String mLDAP_PrincipalSuffix;
private LoginCredentials mLDAP_PrincipalCredentials;
private LDAP_UserObjFactory mUserFactory = new LDAP_UserFactory();
private static final Logger LOGGER = Logger.getLogger(LDAPClient.class.getPackage().getName());
static
{
LOGGER.setUseParentHandlers(false);
}
//---------------------------------------------------------------------------
public LDAPClient setServerURL(String inValue)
{
mLDAP_ServerURL = inValue;
return this;
}
//---------------------------------------------------------------------------
public LDAPClient setUserContext(String inValue)
{
try
{
setUserContext(inValue != null ? new LdapName(inValue) : null);
}
catch (InvalidNameException e)
{
throw new RuntimeException(e);
}
return this;
}
//---------------------------------------------------------------------------
public LDAPClient setUserContext(LdapName inValue)
{
mLDAP_UserContext = inValue;
return this;
}
//---------------------------------------------------------------------------
public LDAPClient setGroupContext(String inValue)
{
try
{
setGroupContext(inValue != null ? new LdapName(inValue) : null);
}
catch (InvalidNameException e)
{
throw new RuntimeException(e);
}
return this;
}
//---------------------------------------------------------------------------
public LDAPClient setGroupContext(LdapName inValue)
{
mLDAP_GroupContext = inValue;
return this;
}
//---------------------------------------------------------------------------
public LDAPClient setPrincipalContext(String inValue)
{
try
{
setPrincipalContext(inValue != null ? new LdapName(inValue) : null);
}
catch (InvalidNameException e)
{
throw new RuntimeException(e);
}
return this;
}
//---------------------------------------------------------------------------
public LDAPClient setPrincipalContext(LdapName inValue)
{
mLDAP_PrincipalContext = inValue;
return this;
}
//---------------------------------------------------------------------------
public LDAPClient setPrincipalSuffix(String inValue)
{
mLDAP_PrincipalSuffix = inValue;
return this;
}
//---------------------------------------------------------------------------
/**
Specifies the credentials to be used to access the LDAP server.
* @param inValue the security principal credentials
* @return this LDAPClient object to facilitate method chaining
*/
public LDAPClient setPrincipalCredentials(LoginCredentials inValue)
{
mLDAP_PrincipalCredentials = inValue;
return this;
}
//---------------------------------------------------------------------------
public LDAPClient setPrincipalFieldName(String inValue)
{
mLDAP_PrincipalFieldName = inValue;
return this;
}
//---------------------------------------------------------------------------
public LDAP_UserObjFactory getUserFactory()
{
return mUserFactory;
}
//---------------------------------------------------------------------------
public LDAPClient setUserFactory(LDAP_UserObjFactory inValue)
{
if (null == inValue)
{
throw new InvalidValueException("The user factory cannot be set to null!");
}
mUserFactory = inValue;
return this;
}
//---------------------------------------------------------------------------
// TODO: Should this method return a more complex result that could contain more info about failures?
public boolean authenticate(LoginCredentials inCredentials)
{
crosscheck();
boolean authenticated = false;
DirContext ctx = null;
try
{
// Create the initial context
ctx = getInitialDirContext(inCredentials);
if (ctx != null)
{
authenticated = true;
}
/*
// get more attributes about this user
SearchControls scs = new SearchControls();
scs.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attrNames = { "mail", "cn" };
scs.setReturningAttributes(attrNames);
NamingEnumeration nes = ctx.search(mLDAP_UserContext, "uid=" + userName, scs);
if(nes.hasMore())
{
Attributes attrs = ((SearchResult) nes.next()).getAttributes();
System.out.println("mail: " + attrs.get("mail").get());
System.out.println("cn: " + attrs.get("cn").get());
}
*/
}
catch (AuthenticationException e)
{
// If it looks like an Active Directory exception, try to decode it...
String msg = ActiveDirectory.decodeAuthenticationException(e);
if (StringUtil.isSet(msg))
{
new LDAP_Exception(msg, e).printStackTrace();
}
else
{
e.printStackTrace();
}
}
catch (NamingException e)
{
e.printStackTrace();
}
finally
{
if (ctx != null)
{
try
{
ctx.close();
}
catch (NamingException e)
{
// Ignore
}
}
}
return authenticated;
}
//---------------------------------------------------------------------------
public U getInfoForUser(String inQuery)
{
return getInfoForUser(inQuery, null);
}
//---------------------------------------------------------------------------
public U getInfoForUser(String inQuery, List inFields)
{
return getInfoForUser(null, inQuery, inFields);
}
//---------------------------------------------------------------------------
public U getInfoForUser(LdapName inBaseDN, String inQuery)
{
return getInfoForUser(inBaseDN, inQuery, null);
}
//---------------------------------------------------------------------------
public U getInfoForUser(LdapName inBaseDN, String inQuery, List inFields)
{
List users = getInfoForUsers(inBaseDN, inQuery, inFields);
return (CollectionUtil.hasValues(users) ? users.get(0) : null);
}
//---------------------------------------------------------------------------
public List getInfoForUsers(String inQuery)
{
return getInfoForUsers(inQuery, null);
}
//---------------------------------------------------------------------------
public List getInfoForUsers(String inFilter, List inFields)
{
return getInfoForUsers(null, inFilter, inFields);
}
//---------------------------------------------------------------------------
public List getInfoForUsers(LdapName inBaseDN, String inFilter, List inFields)
{
List users = null;
DirContext ctx = null;
try
{
// Create the initial context
ctx = getInitialDirContext(mLDAP_PrincipalCredentials);
// get more attributes about this user
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
Map fieldMap = null;
String[] attributesToRetrieve = new String[] {"*"}; // Default to all attributes
if (CollectionUtil.hasValues(inFields))
{
fieldMap = new HashMap<>(inFields.size());
List attrNames = new ArrayList<>(inFields.size());
for (LDAP_UserField field : inFields)
{
attrNames.add(field.name());
fieldMap.put(field.name(), field);
}
attributesToRetrieve = attrNames.toArray(new String[] {});
}
LdapName baseDN = inBaseDN;
if (null == baseDN)
{
baseDN = mLDAP_UserContext; // Use the default user context
}
searchControls.setReturningAttributes(attributesToRetrieve);
LOGGER.info("LDAP Query " + StringUtil.singleQuote(inFilter) + " in context " + StringUtil.singleQuote(baseDN));
NamingEnumeration enumeration = ctx.search(baseDN, inFilter, searchControls);
while (enumeration.hasMore())
{
if (null == users)
{
users = new ArrayList<>();
}
U user = getUserFactory().createUserObj();
users.add(user);
Attributes attrs = ((SearchResult) enumeration.next()).getAttributes();
NamingEnumeration attrEnum = attrs.getIDs();
while (attrEnum.hasMoreElements())
{
String attrID = attrEnum.nextElement();
if (fieldMap != null)
{
LDAP_UserField field = fieldMap.get(attrID);
if (field != null)
{
Method setter = field.getUserObjectSetter();
if (setter != null)
{
try
{
setter.invoke(user, attrs.get(attrID).get().toString());
}
catch (Exception e)
{
}
}
}
}
user.setField(attrID, attrs.get(attrID).get().toString());
}
}
}
catch (NamingException e)
{
throw new LDAP_Exception(e);
}
finally
{
if (ctx != null)
{
try
{
ctx.close();
}
catch (NamingException e)
{
}
}
}
return users;
}
//---------------------------------------------------------------------------
public List getUsersForGroup(String inFilter)
{
List users = null;
DirContext ctx = null;
try
{
// Create the initial context
ctx = getInitialDirContext(mLDAP_PrincipalCredentials);
// get more attributes about this user
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
Map fieldMap = null;
String[] attributesToRetrieve = new String[] {"*"}; // Default to all attributes
searchControls.setReturningAttributes(attributesToRetrieve);
LOGGER.info("LDAP Query " + StringUtil.singleQuote(inFilter) + " in context " + StringUtil.singleQuote(mLDAP_GroupContext));
NamingEnumeration enumeration = ctx.search(mLDAP_GroupContext, inFilter, searchControls);
while (enumeration.hasMore())
{
Attributes attrs = ((SearchResult) enumeration.next()).getAttributes();
NamingEnumeration attrEnum = attrs.getIDs();
while (attrEnum.hasMoreElements())
{
String attrID = attrEnum.nextElement();
if (attrID.equalsIgnoreCase("member")
|| attrID.equalsIgnoreCase("uniquemember"))
{
Attribute attr = attrs.get(attrID);
users = new ArrayList<>(attr.size());
NamingEnumeration memberEnum = (NamingEnumeration) attr.getAll();
while (memberEnum.hasMoreElements())
{
LdapName userDN = new LdapName(memberEnum.nextElement());
users.add(getInfoForUser(userDN, userDN.remove(userDN.size() - 1).toString()));
}
}
}
}
}
catch (NamingException e)
{
throw new LDAP_Exception(e);
}
finally
{
if (ctx != null)
{
try
{
ctx.close();
}
catch (NamingException e)
{
}
}
}
return users;
}
//###########################################################################
// PRIVATE METHODS
//###########################################################################
//---------------------------------------------------------------------------
/**
Checks to run before an operation.
*/
private void crosscheck()
{
if (null == mLDAP_ServerURL)
{
throw new LDAP_Exception("No LDAP server has been specified!");
}
}
//---------------------------------------------------------------------------
private InitialDirContext getInitialDirContext(LoginCredentials inCredentials)
throws NamingException
{
crosscheck();
// creating environment for initial context
Hashtable env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
LOGGER.info("Setting provider URL to " + StringUtil.singleQuote(mLDAP_ServerURL));
env.put(Context.PROVIDER_URL, mLDAP_ServerURL);
// env.put(Context.SECURITY_AUTHENTICATION, "simple");
if (null == inCredentials)
{
throw new LDAP_Exception("No credentials specified!");
}
String securityPrincipal = inCredentials.getUser(); // Active Directory may not want more than this
if (mLDAP_PrincipalContext != null)
{
securityPrincipal = mLDAP_PrincipalFieldName + "=" + inCredentials.getUser() + (mLDAP_PrincipalContext != null ? "," + mLDAP_PrincipalContext : "");
}
else if (StringUtil.isSet(mLDAP_PrincipalSuffix))
{
securityPrincipal += mLDAP_PrincipalSuffix;
}
LOGGER.info("Setting security principal to " + StringUtil.singleQuote(securityPrincipal));
env.put(Context.SECURITY_PRINCIPAL, securityPrincipal);
env.put(Context.SECURITY_CREDENTIALS, inCredentials.getPasswordString());
LOGGER.info("Establishing LDAP connection...");
// Create the initial context
return new InitialDirContext(env);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy