package com.ecyrd.jspwiki.auth.modules;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
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 javax.naming.directory.SearchControls;
import org.apache.log4j.Logger;
import com.ecyrd.jspwiki.NoRequiredPropertyException;
import com.ecyrd.jspwiki.WikiEngine;
import com.ecyrd.jspwiki.auth.UserProfile;
import com.ecyrd.jspwiki.auth.WikiAuthenticator;
import com.ecyrd.jspwiki.providers.ProviderException;
/**
* Provides a simple LDAP based authenticator. Following properties are
* required:
*
* - jspwiki.authenticator - name of our class: LDAPAuthenticator
* - jspwiki.ldapAuthenticator.serverurl - URL of the server used for
* authentication (ex: ldap://myserver/)
* - jspwiki.ldapAuthenticator.binddn - DN of an existing user used
* when searching entries (ex: cn=myuser,dc=in,dc=mydomain)
* - jspwiki.ldapAuthenticator.binddn-password - Password for the
* previous DN (ex: mypassword)
* - jspwiki.ldapAuthenticator.accountattribute - attribute to search
* for (ex, for a Windows Directory: sAMAccountName)
* - jspwiki.ldapAuthenticator.searchbase - The DN of the branch of
* the directory where all searches should start from. (ex: dc=mydomain)
*
*
* @author Sebastien Tanguy
*
*/
public class LDAPAuthenticator implements WikiAuthenticator {
public static final String PROP_BASE = "jspwiki.ldapAuthenticator.";
public static final String PROP_SERVERURL = PROP_BASE + "serverurl";
private String m_serverURL;
public static final String PROP_BINDDN = PROP_BASE + "binddn";
private String m_bindDN;
public static final String PROP_BINDDNPASSWORD = PROP_BASE
+ "binddn-password";
private String m_bindDNPassword;
public static final String PROP_ACCOUNTATTRIBUTE = PROP_BASE
+ "accountattribute";
private String m_accountAttribute;
public static final String PROP_SEARCHBASE = PROP_BASE + "searchbase";
private String m_searchbase;
private SearchControls searchControls = new SearchControls();
static Logger log = Logger.getLogger(LDAPAuthenticator.class);
public void initialize(Properties props) throws NoRequiredPropertyException {
log.debug("initializing LDAPAuth");
m_serverURL = WikiEngine.getRequiredProperty(props, PROP_SERVERURL);
m_bindDN = WikiEngine.getRequiredProperty(props, PROP_BINDDN);
m_bindDNPassword = WikiEngine.getRequiredProperty(props,
PROP_BINDDNPASSWORD);
m_accountAttribute = WikiEngine.getRequiredProperty(props,
PROP_ACCOUNTATTRIBUTE);
m_searchbase = WikiEngine.getRequiredProperty(props, PROP_SEARCHBASE);
}
public boolean authenticate(UserProfile wup) {
if (wup == null || wup.getName() == null)
return (false);
log.debug("getting initial context");
DirContext initialContext = getContext(m_serverURL, m_bindDN,
m_bindDNPassword);
log.debug("getting userDN through initial context : "
+ initialContext.toString());
String userDN = getDN(initialContext, wup.getName());
log.debug("real authentication phase with user DN and password");
DirContext userContext = getContext(m_serverURL, userDN, wup
.getPassword());
return userContext != null;
}
public boolean canChangePasswords() {
return false;
}
public void setPassword(UserProfile wup, String password)
throws ProviderException {
}
protected DirContext getContext(String ldapHost, String DN, String password) {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.SECURITY_CREDENTIALS, password);
props.put(Context.SECURITY_PRINCIPAL, DN);
props.put(Context.PROVIDER_URL, ldapHost);
// props.put(
// Context.INITIAL_CONTEXT_FACTORY,
// "com.sun.jndi.ldap.LdapCtxFactory" );
// props.put(Context.SECURITY_CREDENTIALS, "rowner1");
// props.put(Context.SECURITY_PRINCIPAL,
// "cn=rowner,ou=Admins,dc=vb,dc=org");
// props.put(Context.PROVIDER_URL, "ldap://10.180.232.71:389");
//
DirContext ctx = null;
try {
ctx = new InitialDirContext(props);
} catch (Exception ex) {
ex.printStackTrace();
}
return ctx;
}
protected String getDN(DirContext ctx, String username) {
if (null == ctx) {
return null;
}
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// username = "cbberniu";
// Attributes matchAttrs = new BasicAttributes(true); // ignore
// attribute name case
// matchAttrs.put(new BasicAttribute( m_accountAttribute, username ));
try {
// ctx.search(searchBase, filter, ctls);
// searchEngine.setFilter("(&(uid="+ userId +"))");
NamingEnumeration answer = ctx.search(m_searchbase, "(&(" + m_accountAttribute +"="
+ username + "))", searchControls);
// while (answer.hasMore()) {
// SearchResult sr = (SearchResult)answer.next();
// for( NamingEnumeration ae = sr.getAttributes().getAll();
// ae.hasMore(); )
// {
// Attribute attr = (Attribute)ae.next();
// for (NamingEnumeration e = attr.getAll(); e.hasMore(); )
// {
// return (String)e.next();
// }
// }
// }
if (answer.hasMoreElements()) {
SearchResult sr = (SearchResult) answer.next();
// get DN
// DN = sr.getName();
// fullDN = DN + "," + searchBase;
// attributes = sr.getAttributes();
return sr.getName() + "," + m_searchbase;
}
else {
if (log.isDebugEnabled())
log.debug("getDN(DirContext, String): " + username
+ " does not exists !");
return null;
}
} catch (Exception e) {
e.printStackTrace();
if (log.isDebugEnabled()) {
log.debug("getDN(DirContext, String): " + e.getMessage()); //$NON-NLS-1$
}
}
return null;
}
// public static void main(String[] args) {
//
//
// LDAPAuthenticator aaa = new LDAPAuthenticator();
// aaa.getContext("","","");
// System.out.println("aaa:" + aaa.getDN(aaa.getContext("","",""),"uid") );
//
// }
}