tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <vgan...@yahoo.com>
Subject class LDADRealm
Date Fri, 09 Feb 2001 17:06:47 GMT
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>&lt;secutity-constraint&gt;</code> and
 * <code>&lt;login-config&gt;</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>&lt;RequestInterceptor&gt;</code> tag that refers to
 * <code>SimpleRealm</code> and insert a new
 * <code>&lt;RequestInterceptor&gt;</code> similar to:
 * <table align="center"><tr><td><code>
 * 			&lt;RequestInterceptor<br>
 * 				&nbsp;&nbsp;className="LDAPRealm"<br>
 * 				&nbsp;&nbsp;debug="99"<br>
 * 				&nbsp;&nbsp;version="3"<br>
 * 				&nbsp;&nbsp;port="389"<br>
 * 				&nbsp;&nbsp;host="ldap.mycompany.com"<br>
 * 				&nbsp;&nbsp;org="MyCompany"<br>
 * 				&nbsp;&nbsp;unit="mydept" /&gt;
 * </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>
 * 	&lt;user name="jdoe"   password="" roles="role1,role2" /&gt;
 * </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&#64;yahoo.com]
 * @author Christian Porter  [cporter&#64;stshotelnet.com]
 * @author Tom Kotsines [tkosines&#64;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 );
    }

}


Mime
View raw message