/** **************************************************************************** * * Copyright (c) 2001-2004 Tortuga Technologies Pty Ltd. All rights reserved. * * This is unpublished proprietary source code of Tortuga Technologies Pty Ltd. * The copyright notice above does not evidence any actual or intended * publication of such source code. * ******************************************************************************* * * File: au.com.tortuga.ozibug.auth.example.LDAPAuthenticationHandler.java * * Description: Example LDAP Authentication handler * **************************************************************************** */ package au.com.tortuga.ozibug.auth.example; // application specific imports import au.com.tortuga.ozibug.auth.AuthenticationHandler; import au.com.tortuga.ozibug.util.LifeCycle; // external imports import org.apache.log4j.Category; // ldap imports import com.novell.ldap.LDAPAttribute; import com.novell.ldap.LDAPConnection; import com.novell.ldap.LDAPEntry; import com.novell.ldap.LDAPException; import com.novell.ldap.LDAPSearchResults; // servlet imports import javax.servlet.http.HttpServletRequest; // java imports import java.util.Iterator; import java.util.Map; import java.text.MessageFormat; /** **************************************************************************** * * This example Authentication Handler uses an LDAP server * to verify the details of the user attempting access against. * The user id and password are obtained from the HttpServletRequest and then * the password verified against the plain text password retrieved * from the LDAP Server. *
* Note: this is an example which doesn't include * handling failed, dropped or broken connections to the LDAP server. * nor does it terminate and release any resources through * its destroy() method. *
** The following properties must be configured in the properties file as * they configure the details of the LDAP server and the searches carried * out against it. *
*
* authentication.handler.1=au.com.tortuga.ozibug.auth.example.LDAPAuthenticationHandler
* authentication.handler.1.parameter.1=ldap.host=ldap-host.yourdomain.com
* authentication.handler.1.parameter.2=ldap.port=389
* authentication.handler.1.parameter.3=ldap.bind.dn=cn=Manager,o=Your Company
* authentication.handler.1.parameter.4=ldap.bind.passwd=bindPassword
* authentication.handler.1.parameter.5=ldap.search.base=o=Your Company
* authentication.handler.1.parameter.6=ldap.search.filter=(&(uid={0})(objectclass=inetorgperson))
*
*
* @author Tortuga Technologies
*
**************************************************************************** */
public class LDAPAuthenticationHandler implements AuthenticationHandler,LifeCycle {
/** **************************************************************************
*
* Class (static) variables - public/protected/package/private
*
************************************************************************** */
/** logging category */
private static final Category log =
Category.getInstance(
"au.com.tortuga.ozibug.auth.example.LDAPAuthenticationHandler" );
/** the name of this handler (LDAP) */
private static final String NAME = "LDAP";
/**
* a description of how this handler authenticates (name/password in
* http request against LDAP database)
*/
private static final String DESCRIPTION =
"uses name/password in http request against LDAP database";
/** LDAP host property name */
public static final String LDAP_HOST = "ldap.host";
/** LDAP port property name */
public static final String LDAP_PORT = "ldap.port";
/** LDAP bind dn property name */
public static final String LDAP_BIND_DN = "ldap.bind.dn";
/** LDAP bind password property name */
public static final String LDAP_BIND_PASSWD = "ldap.bind.passwd";
/** LDAP search base property name */
public static final String LDAP_SEARCH_BASE = "ldap.search.base";
/** LDAP search filter property name */
public static final String LDAP_SEARCH_FILTER = "ldap.search.filter";
/** **************************************************************************
*
* Instance variables - public/protected/package/private
*
************************************************************************** */
/** holds the configuration information passed in at initialization time */
private Map ldapDetails = null;
/** the connection to the LDAP server */
private LDAPConnection lc = null;
/** the scope of the search to carry out on the server for each user */
private int searchScope = 0;
/** the base that we will search from */
private String searchBase = null;
/** the LDAP search filter which will return the user's details given the id */
private String searchFilter = null;
/** **************************************************************************
*
* Called on initialization this method stores the LDAP configuration and
* then uses it to connect to the LDAP Server.
*
* @param handlerInfo configuration information
* @see LifeCycle#init
*
************************************************************************** */
public void init( Map handlerInfo ) throws Exception {
String logId = "init";
// log the configuration parameters
Iterator it = handlerInfo.keySet().iterator();
while ( it.hasNext() ) {
String name = (String) it.next();
String value = (String) handlerInfo.get( name );
log.debug( logId + ": " +
name + " = " + (name.equals(LDAP_BIND_PASSWD) ? "******" : value) );
}
// save the configuration
this.ldapDetails = handlerInfo;
// and connect to the LDAP server
connectLDAP();
// and we're initialized
log.info( logId + ": done" );
} // init
/** **************************************************************************
*
* Called when the Ozibug servlet is terminated by the container.
*
* @see LifeCycle#destroy
*
************************************************************************** */
public void destroy() {
String logId = "destroy";
// free resources here ...
// and we're done
log.info( logId + ": done" );
} // destroy
/** **************************************************************************
*
* Returns the name of this Authentication Handler.
*
* @return the name of this authentication handler
* @see AuthenticationHandler#getName
*
************************************************************************** */
public String getName() {
return NAME;
} // getName
/** **************************************************************************
*
* Returns a description of this Authentiction Handler.
*
* @return a brief description of how this authentication handler works
* @see AuthenticationHandler#getDescription
*
************************************************************************** */
public String getDescription() {
return DESCRIPTION;
} // getDescription
/** **************************************************************************
*
* Compares the given user information against that stored on an LDAP Server;
* Note: doesn't take into account encrypted passwords.
*
* @param context the context used to pass objects between handlers
* @return true if an authentication was achieved; false otherwise
* @see AuthenticationHandler#authenticate
*
************************************************************************** */
public boolean authenticate( Map context ) {
String logId = "authenticate";
boolean result = false;
try {
// get the HttpServletRequest from the context
HttpServletRequest req =
(HttpServletRequest) context.get( HTTP_REQUEST );
// get the users' parameters from the request
String id = req.getParameter( "user" );
String passwd = req.getParameter( "password" );
// the password from the ldap server, we will compare against
String ldapPasswd = null;
// without these there's no point in continuing !
if ( (id == null) || (passwd == null) ) {
// return quietly
return result;
}
// carry out a search for the specified user (id) in the LDAP server
LDAPSearchResults searchResults = null;
try {
searchResults =
lc.search(
searchBase,
searchScope,
MessageFormat.format( searchFilter, new Object[] { id } ),
null, // return all attributes
false // return attributes and values
);
}
catch ( Exception e ) {
// search failed, log an informative message
log.debug( logId +": LDAP search(" + id + ") failed, " + e, e );
// return false, the authentication failed
return false;
}
// process the search results (hopefully only one)
while ( searchResults.hasMore() ) {
// get the LDAP database entry
LDAPEntry nextEntry = null;
try {
nextEntry = searchResults.next();
}
catch( LDAPException e ) {
// something wrong with this one, move on to the next
continue;
}
// get the LDAP password attribute
LDAPAttribute attribute = nextEntry.getAttribute( "userPassword" );
ldapPasswd = attribute.getStringValue();
// print some useful debugging
log.debug( logId +
": retrieved details of " + nextEntry.getDN() + ", id = " + id );
break;
}
// check the password from LDAP against the supplied password
if ( passwd.equals(ldapPasswd) ) {
// passwords match, set the return result to true
result = true;
// set the authenticated user id into the context
context.put( USER_NAME, id );
}
}
catch ( Exception e ) {
// unexpected exception while processing, log it and continue
log.error( logId + ": failed, " + e, e );
}
// return the status of this authentication attempt
return result;
} // authenticate
/** **************************************************************************
*
* Connect to the LDAP server using the parameters in the * handlerInfo map
* which was passed in the init() method.
*
* @throws Exception if the connection or bind failed
*
************************************************************************** */
private void connectLDAP() throws Exception {
String logId = "connectLDAP";
// extract the details
int ldapPort = LDAPConnection.DEFAULT_PORT;
try {
ldapPort =
Integer.parseInt( (String) this.ldapDetails.get(LDAP_PORT) );
}
catch ( Exception ignored ) {}
searchScope = LDAPConnection.SCOPE_SUB;
int ldapVersion = LDAPConnection.LDAP_V3;
String ldapHost = (String) this.ldapDetails.get( LDAP_HOST );
String loginDN = (String) this.ldapDetails.get( LDAP_BIND_DN );
String password = (String) this.ldapDetails.get( LDAP_BIND_PASSWD );
searchBase = (String) this.ldapDetails.get( LDAP_SEARCH_BASE );
searchFilter = (String) this.ldapDetails.get( LDAP_SEARCH_FILTER );
// make a connection
lc = new LDAPConnection();
// connect to the server
lc.connect( ldapHost, ldapPort );
log.debug( logId +
": connecting to ldap://" + ldapHost + ":" + ldapPort + "/" );
// bind to the server
lc.bind( ldapVersion, loginDN, password.getBytes("UTF8") );
log.debug( logId + ": bound as \"" + loginDN + "\"" );
} // connectLDAP
} // LDAPAuthenticationHandler