You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by vg...@yahoo.com on 2001/02/09 18:06:47 UTC
class LDADRealm
Hello,
First an apology: Sorry, I know the right way to submit code is through
the CVS Repository, but I really just wanted to give this one useful class
to the project (if you want it.) Anyway, I wrote it, I documented it pretty
well, I thought it might be useful to others, it may need to be tweaked (but
works as is), here it is:
Oh yeah, it's for tomcat 3.2.1 and if someone decides to put it into CVS,
please notify me at vganora@yahoo.com
-Vik
//****************************************************
//package org.apache.tomcat.request;
//import org.apache.tomcat.core.BaseInterceptor;
import org.apache.tomcat.core.ContextManager;
import org.apache.tomcat.core.Request;
import org.apache.tomcat.core.Response;
import org.apache.tomcat.core.TomcatException;
import org.apache.tomcat.util.SecurityTools;
import org.apache.tomcat.request.SimpleRealm;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.DirContext;
import java.util.Properties;
import java.util.Hashtable;
/**
* An extension of <code> SimpleRealm </code> that performs authentication
* against an LDAP server. Authorization is still handled
* by <code> SimpleRealm </code>.<br>
* To use:
* <ul>
* <li>Setup <code><secutity-constraint></code> and
* <code><login-config></code> tags in your web application's
* <code>web.xml</code> file as you normally would. (For an example see
* <code>%TOMCAT_HOME%/webapps/examples/WEB-INF/web.xml</code>)</li>
* <li>Edit <code>%TOMCAT_HOME%/conf/server.xml</code>. Comment out the
* <code><RequestInterceptor></code> tag that refers to
* <code>SimpleRealm</code> and insert a new
* <code><RequestInterceptor></code> similar to:
* <table align="center"><tr><td><code>
* <RequestInterceptor<br>
* className="LDAPRealm"<br>
* debug="99"<br>
* version="3"<br>
* port="389"<br>
* host="ldap.mycompany.com"<br>
* org="MyCompany"<br>
* unit="mydept" />
* </code><td><tr></table>
* <table align="center"><tr><td>
* <b><code>RequestInterceptor</code> Element Attributes</b><br>
* <dl>
* <dt>classname</dt>
* <dd>Must be "<code>org.apache.tomcat.request.LDAPRealm</code>"
* <b>(Required)</b></dd>
* <dt>debug</dt>
* <dd>Make this greater than zero to receive useful debugging information.
* (Optional)</dd>
* <dt>version</dt>
* <dd>The version of LDAP the server is using. (Optional, default is
3.)</dd>
* <dt>port</dt>
* <dd>The port the LDAP server is running on. (Optional, default is
389.)</dd>
* <dt>host</dt>
* <dd>The name of the host the LDAP server is running on. (Optional,
default
* is "localhost".)</dd>
* <dt>org</dt>
* <dd>The "o=" or root naming context LDAP parameter. (Optional, not used
if
* not set.)</dd>
* <dt>unit</dt>
* <dd>The "ou=" or organizational unit LDAP parameter. (Optional, not used
if
* not set.)</dd>
* <dl>
* <td><tr></table></li>
* <li>Edit <code>%TOMCAT_HOME%/conf/tomcat-users.xml</code> so that
* authorization, which is defered to <code>SimpleRealm</code>, will work as
* you want it to. <code>user</code> elements should look similar to:
* <table align="center"><tr><td><code>
* <user name="jdoe" password="" roles="role1,role2" />
* </code><td><tr></table>
* Note that the <code>password</code> attribute is specified as an empty
* string, but will actually be checked against the LDAP server at runtime.
* </li>
* </ul>
* <b>Note:</b> Until <code>LDAPRelm</code> becomes part of Tomcat it must
be made
* available to the server (which means jaring it and placing the jar into
* <code>%TOMACT_HOME%/lib</code>.) Simply placing it in your web
application's
* classpath won't do.<br>
* <b>Note:</b> <code>LDAPRelm</code> was developed against Netscape
Directory
* Server and may need to be tweeked to work with other LDAP servers.
*
* @author Victor Ganora [vganora@yahoo.com]
* @author Christian Porter [cporter@stshotelnet.com]
* @author Tom Kotsines [tkosines@stshotelnet.com]
* @version 1.0
* @see org.apache.tomcat.request.SimpleRealm
* @see org.apache.tomcat.request.JDBCRealm
* @see org.apache.tomcat.core.BaseInterceptor
*/
//public class LDAPRealm extends BaseInterceptor {
public class LDAPRealm extends SimpleRealm {
private static final String DEFAULT_CTX =
"com.sun.jndi.ldap.LdapCtxFactory";
private static int version = 3;
private static int port = 389;
private static String host = "localhost";
private static String org;
private static String unit;
/**
* Sets the version of LDAP the server is using.
*
* @param version The version of LDAP the server is using.
*/
public void setVersion( int version ) {
this.version = version;
}
/**
* Sets the port the LDAP server is running on.
*
* @param port The port the LDAP server is running on.
*/
public void setPort( int port ) {
this.port = port;
}
/**
* Sets the name of the host the LDAP server is running on.
*
* @param host The name of the host the LDAP server is running on.
*/
public void setHost( String host ) {
this.host = host;
}
/**
* Sets the "o=" or root naming context LDAP parameter.
*
* @param org The "o=" or root naming context LDAP parameter.
*/
public void setOrg( String org ) {
this.org = org;
}
/**
* Sets the "ou=" or organizational unit LDAP parameter.
*
* @param unit The "ou=" or organizational unit LDAP parameter.
*/
public void setUnit( String unit ) {
this.unit = unit;
}
/**
* <b>Description copied from interface: RequestInterceptor</b><br>
* This callback is used to extract and verify the user identity and
* credentials. It will set the RemoteUser field if it can authenticate.
* The auth event is generated by a user asking for the remote user
field
* of by tomcat if a request requires authenticated id.
*
* @param req The request.
* @param resp The response.
*/
public int authenticate( Request req, Response resp ) {
// Extract the credentials
Hashtable cred = new Hashtable();
SecurityTools.credentials( req, cred );
// This realm will use only username and password callbacks
String user = (String) cred.get( "username" );
String password = (String) cred.get( "password" );
if( debug > 0 ) {
log( ( new StringBuffer( 128 ) ).append( "Verify user=" )
.append( user )
.append( " pass=" )
.append( password )
.toString() );
}
try {
if( checkPassword( user, password ) ) {
if( debug > 0 ) {
log( ( new StringBuffer( 128 ) )
.append( "Auth ok, user=" )
.append( user )
.toString() );
}
req.setRemoteUser( user );
org.apache.tomcat.core.Context ctx = req.getContext();
if (ctx != null)
req.setAuthType(ctx.getAuthMethod());
}
}
catch( NamingException e ) {
log( ( new StringBuffer( 128 ) )
.append( "User aurhorization Failure: user=" )
.append( user )
.append( " pass=" )
.append( password )
.append( "\n\t" )
.append( e.getMessage() )
.toString() );
}
return 0;
}
/**
* If there are any errors with the LDAP connection, executing the
request
* or anything we return false (don't authenticate).
*
* @param userid The username ("uid=" parameter) to be authenticated.
* @param pwd The password of the user to be authenticated.
* @return True is the user was successfully authenticated, otherwise
false
* @exception javax.naming.NamingException If a problem was encountered
* while creating the initial context.
*/
public boolean checkPassword( String userid, String pwd )
throws NamingException {
if ( userid != null && pwd != null &&
connect( version, host, port, org, unit, userid, pwd ) != null )
{
return true;
}
return false;
}
/**
* Attempts to connect to the LDAP server with the specified credentials
* and return a <code>DirContext</code>.
*
* @param ver The version of LDAP the server is using.
* @param host The name of the host the LDAP server is running on.
* @param port The port the LDAP server is running on.
* @param org The "o=" or root naming context LDAP parameter.
* @param unit The "ou=" or organizational unit LDAP parameter.
* @param userid The username ("uid=" parameter) to be authenticated.
* @param pwd The password of the user to be authenticated.
* @return The specified <code>DirContext</code>.
* @exception javax.naming.NamingException If a problem was encountered
* while creating the initial context.
*/
public DirContext connect( int ver,
String host,
int port,
String org,
String unit,
String userid,
String pwd )
throws NamingException {
Properties env = new Properties();
env.put( "java.naming.ldap.version", String.valueOf( ver ) );
env.put( Context.INITIAL_CONTEXT_FACTORY, DEFAULT_CTX );
env.put( Context.SECURITY_AUTHENTICATION, "simple" );
StringBuffer providerBuffer = new StringBuffer ( 128 )
.append( "ldap://" )
.append( host )
.append( ":" )
.append( port );
if ( org != null ){
providerBuffer.append( ",o=" )
.append( org );
}
env.put( Context.PROVIDER_URL, providerBuffer.toString() );
StringBuffer principalBuffer = new StringBuffer ( 128 )
.append( "uid=" )
.append( userid );
if ( unit != null ){
principalBuffer.append( ",ou=" )
.append( unit );
}
if ( org != null ){
principalBuffer.append( ",o=" )
.append( org );
}
env.put( Context.SECURITY_PRINCIPAL, principalBuffer.toString() );
env.put( Context.SECURITY_CREDENTIALS, pwd );
return new InitialDirContext( env );
}
}