Complete Contents
Preface
Chapter 1 Understanding LDAP
Chapter 2 Using the Netscape Directory SDK for Java
Chapter 3 Quick Start
Chapter 4 Writing an LDAP Client
Chapter 5 Using the LDAP Java Classes
Chapter 6 Searching the Directory
Chapter 7 Using Filter Configuration Files
Chapter 8 Adding, Updating, and Deleting Entries
Chapter 9 Comparing Values in Entries
Chapter 10 Working with LDAP URLs
Chapter 11 Getting Server Information
Chapter 12 Connecting Over SSL
Chapter 13 Working with LDAP Controls
Chapter 14 Using SASL Authentication
Chapter 15 Using Netscape's JNDI Service Provider
Chapter 16 Working with Extended Operations
Chapter 17 Using the Asynchronous Interface
Glossary
Directory SDK for Java 4.0 Programmer's Guide: Using SASL Authentication
Previous Next Contents Index


Chapter 14 Using SASL Authentication

This chapter describes the process of using a SASL mechanism to authenticate an LDAP client to an LDAP server.

The chapter includes the following sections:


Understanding SASL
The Simple Authentication and Security Layer (SASL) is an authentication method. It allows you to use mechanisms other than simple passwords and SSL for authenticating over connection-based protocols, such as LDAP.

All SASL mechanisms are registered with the Internet Assigned Numbers Authority (IANA). Included among these mechanisms are KERBEROS_V4, GSSAPI, and several others. The client implements these mechanisms through the use of mechanism drivers. These drivers are classes that contain the code required for authenticating over a given mechanism.

When a client attempts to authenticate to a Directory Server using the LDAPConnection.authenticate method, it can specify a list of SASL mechanisms to use. If the client does not specify any mechanisms, the SDK will query the server to find out which mechanisms it supports. If the SDK and the server have a common mechanism, authentication can occur.

If the server supports a requested mechanism, it responds with one or more challenges. In order to authenticate, the client must correctly respond to these challenges. This is handled transparently by the SDK using a mechanism driver.

If the server does not support any of the requested mechanisms, the SDK throws an AuthenticationNotSupportedException.

If the mechanism driver requires additional authentication data from the client it sends a Callback object to the client. To prepare for this, the client implements a CallbackHandler and passes it to the SDK. If the SASL mechanism needs to obtain additional credentials or notify the client of errors during the SASL negotiations, it calls the CallbackHandler object with Callback objects for each item to be processed. The CallbackHandler then decides how to proceed.

The Netscape Directory SDK for Java includes a package called com.netscape.sasl which contains the code necessary to perform all of the steps involved in SASL authentication.


Preparing to Use SASL Authentication
Before performing SASL authentication

The rest of this section describes how to do this using the Netscape Directory SDK for Java and the Netscape Directory Server.

Supporting SASL on the Server
If you are running Netscape Directory Server 3.0 or later, you can write your own server plug-in to handle SASL authentication.

This pre-operation bind plug-in uses a registered SASL mechanism to

For more information on how to write this plug-in, see "Defining Functions for Authentication" in the Netscape Directory Server Plug-In Programmer's Guide.

For more information on SASL mechanisms, see "For More Information" at the end of this chapter.

Supporting SASL on the Client
In order to authenticate over SASL, you will need to have a mechanism available in your SASL client package. If you have obtained a ClientFactory class that can produce a SASL mechanism which your server supports, you can name its package in your code.

There are two ways to do this. You can either

or

For example, if you have a class called mysecurity.sasl.ClientFactory which is capable of producing a SaslClient object for one or more mechanisms, you could either write:

Hashtable props = new Hashtable();
props.put ( "javax.security.sasl.client.pkgs", "mysecurity.sasl" );
ld.authenticate( dn, props, cbh );
or

Sasl.setSaslClientFactory (new mysecurity.sasl.ClientFactory() );
ld.authenticate( dn, props, cbh );
The arguments are as follows:

Table 14.1 Arguments for LDAPConnection.authenticate (above)
Argument Name

Description

dn
Authentication DN
props
Any optional properties that the mechanism accepts. See Table 14.3 for details.
cbh
An instance of the CallbackHandler implemented in your application.

Implementing javax.security.auth.callback
Some SASL mechanisms require additional credentials during the authentication process. In order to provide this additional information, your SASL client may need to implement Callback objects and a CallbackHandler to list them. Callback and CallbackHandler are part of the javax.security.auth.callback package. The package is part of the Java Authentication and Authorization Service (JAAS) and is contained in the jaas.jar file.

To install the javax.security.auth.callback classes:

  1. Locate the jaas.jar file
  2. Add the jaas.jar file to your CLASSPATH
  3. Import javax.security.auth.callback.* in your code.
The following is an example of Callback and CallbackHandler implementations.

class SampleCallbackHandler implements CallbackHandler {
   SampleCallbackHandler( String userName ) {
      userName = userName;
   }
   /** Invoke the requested Callback */
   public void invokeCallback(Callback[] callbacks)
      throws java.io.IOException, UnsupportedCallbackException {
         for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof TextOutputCallback) {
               // display the message according to the
               // specified STYLE
               TextOutputCallback toc =
                  (TextOutputCallback)callbacks[i];
               switch (toc.getStyle()) {
                  case TextOutputCallback.ERROR:
                  System.out.println("ERROR: " +
                     toc.getMessage());
                  break;
                  case TextOutputCallback.INFORMATION:
                  System.out.println(toc.getMessage());
                  break;
                  case TextOutputCallback.WARNING:
                     System.out.println("WARNING: " +
                        toc.getMessage());
                     break;
                  }
               } else if (callbacks[i] instanceof
                  TextInputCallback) {
                     // prompt the user for information
                     TextInputCallback tic =
                        (TextInputCallback)callbacks[i];
                     // display the prompt like this:
                     // prompt [default_reply]:
                     System.err.print(tic.getPrompt() +
                                 " [" +
                                 tic.getDefaultText() +
                                 "]: ");
                     System.err.flush();
                     BufferedReader reader =
                        new BufferedReader(
                           new InputStreamReader(System.in));
                        tic.setText(reader.readLine());
               } else if (callbacks[i] instanceof NameCallback) {
                  ((NameCallback)callbacks[i]).setName(
                     _userName );
               } else if (callbacks[i] instanceof
                  PasswordCallback) {
                     // prompt the user for sensitive information
                     PasswordCallback pc =
                        (PasswordCallback)callbacks[i];
                     System.err.print(pc.getPrompt() + " ");
                     System.err.flush();
                     pc.setPassword(readPassword(System.in));
               } else if (callbacks[i] instanceof
                  LanguageCallback) {
                     // Get the language from the locale
                     LanguageCallback lc =
                        (LanguageCallback)callbacks[i];
                     lc.setLocale( Locale.getDefault() );
               } else {
                  throw new UnsupportedCallbackException
                     (callbacks[i], "Unrecognized Callback");
               }
            }
         }
      /** Reads user password from given input stream. */
      private char[] readPassword(InputStream in) {
         // insert code to read a user password from the
         // input stream
      }
   private String _userName = null;
}

Using SASL in the Client
You are ready to authenticate when you have

The following example shows you how to use SASL in an application:

Hashtable props = new Hashtable();
props.put( "javax.security.sasl.client.pkgs",
         "mysecurity.sasl" );
ld.authenticate( dn, props, new SampleCallbackHandler() );
Using the External Mechanism
The Netscape Directory SDK for Java includes a mechanism called EXTERNAL. This mechanism verifies that SSL authentication has already completed before it allows a client to connect over LDAP.

To use the EXTERNAL mechanism:

  1. Bind to the server and authenticate using SSL.
  2. Call the LDAPConnection.authenticate method as follows:
  3. ld = new LDAPConnection();
    ld.authenticate(null, new String[]{"EXTERNAL"}, null, (CallbackHandler)null);
LDAPConnection.authenticate takes the following arguments:

Table 14.2 Arguments taken by the LDAPConnection.authenticate method
Argument Name

Description

dn
Authentication DN
mechanisms
The list of SASL mechanism to use for authentication. If null is specified, the SDK will query the server for all available mechanisms.
props
Any optional properties that the mechanism accepts. See Table 14.3 for more details.
cbh
An instance of the CallbackHandler implemented in your application.

Table 14.3 lists the properties that you can specify for the props argument.

Table 14.3 Acceptable values for the props argument.
Property Name

Description

javax.security.sasl.
encryption.minimum
The minimum key length to be used during the session. The default value is "0" (zero), no session protection. A value of "1" enables integrity protection only.
javax.security.sasl.
encryption.maximum
The maximum key length to be used during the session. The default value is "256".
javax.security.sasl.
server.authentication
A boolean value. "True" if a server must authenticate to the client. The default value is "false".
javax.security.sasl.ip.local
This is the client's IP address in dotted decimal format. This value is required for KERBEROS_V4 authentication. There is no default value.
javax.security.sasl.ip.remote
This is the server's IP address in dotted decimal format. This value is required for KERBEROS_V4 authentication. There is no default value.
javax.security.sasl.
maxbuffer
Specifies the maximum size of the security layer frames. The default is "0" (zero) meaning that the client will not use the security layer. See
javax.security.sasl.
client.pkgs
A bar-separated list of package names that are to be used when locating a SaslClientFactory.

The javadocs for the Directory SDK for Java describe the LDAPConnection interface and authenticate method more fully. For information on using the javadocs, see "Where to Find Reference Information".

Additional SASL Mechanisms
Authentication using a SASL mechanism other than EXTERNAL requires you to implement classes for the mechanism in the client and on the server. For information on obtaining classes for SASL mechanisms see "For More Information".


For More Information
SASL is described in RFC 2222, which you can find at

http://www.ietf.org/rfc/rfc2222.txt 
A current listing of registered SASL mechanisms is available at

http://www.isi.edu/in-notes/iana/assignments/sasl-mechanisms
 

© Copyright 1999 Netscape Communications Corporation. All rights reserved.