package net.sourceforge.solexatools.authentication;
import java.util.Hashtable;
import java.util.List;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchResult;
import org.apache.log4j.Logger;
import com.google.common.collect.Lists;
/**
* This authentication plugin allows the SeqWare Portal to authenticate against the Ontario Institute for Cancer Research (OICR) LDAP
* server.
*
* Users will pass in an email address and password. An associated list of uids that match the email address will be retrieved via an LDAP
* directory search. More than one uid will be returned for users who have multiple credentials. This plugin will loop through the uids and
* attempt to authenticate with the provided password.
*
* @author boconnor
* @version $Id: $Id
*/
public class OICRLdapAuthentication extends Authentication {
static Logger log = Logger.getLogger(OICRLdapAuthentication.class);
/**
* {@inheritDoc}
*
* @return
*/
@Override
public boolean loginSuccess(String uid, String password) {
// uid value is an email address.
return oicrLdapLogin(uid, password);
}
private boolean oicrLdapLogin(String email, String password) {
List<String> uids = Lists.newArrayList();
try {
uids = getUids(findUidsByEmail(email));
} catch (NamingException e) {
log.debug("Failed to locate uids for user [" + email + "] due to ldap exception. ", e);
}
for (String uid : uids) {
if (oicrLdapAuthenticate(uid, password)) {
return true;
}
}
return false;
}
private boolean oicrLdapAuthenticate(String uid, String password) {
boolean result = false;
Hashtable<String, String> env = new Hashtable<>(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://10.0.0.100/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "uid=" + uid + ", ou=People, dc=oicr, dc=on, dc=ca");
env.put(Context.SECURITY_CREDENTIALS, password);
try {
DirContext context = new InitialDirContext(env);
context.close();
result = true;
} catch (NamingException e) {
log.debug("User [" + uid + "] failed to authenticate via ldap. ", e);
}
return result;
}
private NamingEnumeration<SearchResult> findUidsByEmail(String email) throws NamingException {
NamingEnumeration<SearchResult> result;
DirContext context = getDirContext();
try {
// Ignore case when matching.
Attributes matchingAttributes = new BasicAttributes(true);
// Search for object with 'mail' attribute that matches the provided
// 'email' address.
matchingAttributes.put(new BasicAttribute("mail", email));
result = context.search("ou=People, dc=oicr, dc=on, dc=ca", matchingAttributes);
} finally {
context.close();
}
return result;
}
/**
* <p>
* getDirContext.
* </p>
*
* @return a {@link javax.naming.directory.DirContext} object.
* @throws javax.naming.NamingException
* if any.
*/
public DirContext getDirContext() throws NamingException {
Hashtable<String, String> env = new Hashtable<>(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://10.0.0.100/");
DirContext ctx = new InitialDirContext(env);
return ctx;
}
/**
* <p>
* getUids.
* </p>
*
* @param searchResultEnum
* a {@link javax.naming.NamingEnumeration} object.
* @return a {@link java.util.List} object.
* @throws javax.naming.NamingException
* if any.
*/
public List<String> getUids(NamingEnumeration<SearchResult> searchResultEnum) throws NamingException {
List<String> uids = Lists.newArrayList();
while (searchResultEnum.hasMore()) {
SearchResult sr = (SearchResult) searchResultEnum.next();
uids.add((String) sr.getAttributes().get("uid").get());
}
return uids;
}
}