SASL Authentication With &DirectorySDKForJava;
This chapter describes the process of using a SASL mechanism to authenticate
an LDAP client to an LDAP server.
This chapter covers the following topics:
Understanding SASL and Directory
SDK for Java
Preparing to Use SASL Authentication
With Directory SDK for Java
Using SASL in the Client With
Directory SDK for Java
Further Reading About SASL
Understanding SASL and &DirectorySDKForJava;
SASL
defined
The Simple Authentication and Security Layer (SASL) is an authentication
method. SASL 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 that is required for authenticating over a given mechanism.
When a client attempts to authenticate to an LDAP server with the
LDAPConnection.authenticate method, the client can specify a list
of SASL mechanisms to use. If the client does not specify any mechanisms, &DirectorySDKForJava; queries
the server to find out which mechanisms the server supports. If &DirectorySDKForJava; and
the server have a common mechanism, authentication can occur.
If the server supports a requested mechanism, the server responds with
one or more challenges. To authenticate, the client must correctly respond
to these challenges. Client handling is performed transparently by &DirectorySDKForJava; with
a mechanism driver.
If the server does not support any of the requested mechanisms, the
SDK returns an AuthenticationNotSupportedException.
If the mechanism driver requires additional authentication data from
the client, the driver sends a Callback object to the
client. To prepare for the callback, the client implements a CallbackHandler
and passes the handler to &DirectorySDKForJava;. The SASL
mechanism might need additional client credentials. The SASL mechanism might
also notify the client of errors during the SASL negotiations. For either
purpose, the mechanism calls the CallbackHandler object
with Callback objects for each item to be processed.
The CallbackHandler then determines how to proceed.
&DirectorySDKForJava; includes a package, com.netscape.sasl,
that contains the code necessary to perform all of the steps involved in SASL
authentication.
Preparing to Use SASL Authentication With &DirectorySDKForJava;
Before performing SASL authentication, you must do the following:
Ensure that your LDAP server supports at least one SASL mechanism
Ensure that your client environment supports at least one
SASL mechanism supported by the server
SASL Support on the Server
SASL
server-side requirements
&cnDirectoryServer; supports a plug-in API that allows you to write
your own server plug-in to handle SASL authentication. &cnDirectoryServer; also
supports SASL authentication through DIGEST-MD5 and through GSSAPI.
If you write your own plug-in, your plug-in uses a registered SASL mechanism
to do the following:
Get information from a SASL bind request.
Create and send a SASL bind response back to the client.
This response can take the form of a challenge that requires an answer
from the client. The response can also take the form of an error message.
Finally, the response can take the form of a success message indicating that
authentication is complete.
SASL Support on the Client
SASL
client-side requirements
To authenticate over SASL, you must have a mechanism in your SASL client
package. If you have obtained a ClientFactory class
that can produce a SASL mechanism that your server supports, you can name
its package in your code.
This option can be performed in one of two ways:
Request a SASL client. Specify the package in the javax.security.sasl.client.pkgs
property of its Hashtable.
Set the package as the default factory for the session with
the Sasl.setSaslClientFactory method.
For example, you might have a class, mysecurity.sasl.ClientFactory
, capable of producing a SaslClient object
for one or more mechanisms. You could then write either of the two following
bits of code:
Hashtable props = new Hashtable();
props.put("javax.security.sasl.client.pkgs", "mysecurity.sasl");
ld.authenticate(dn, props, cbh);
Sasl.setSaslClientFactory (new mysecurity.sasl.ClientFactory());
ld.authenticate(dn, props, cbh);
The parameters used have the following descriptions:
dn
Authentication DN
props
Optional properties that the mechanism accepts
Refer to Using
the External Mechanism for details.
cbh
Instance of CallbackHandler that is
implemented in your application
Implementing javax.security.auth.callback
authentication
implementing SASL callbacks
callbacks
implementing for SASL
SASL
implementing callbacks
Some SASL mechanisms require additional credentials during the authentication
process. To provide this additional information, your SASL client might need
to implement Callback objects and a CallbackHandler
to list credentials. Callback and
CallbackHandler are part of the javax.security.auth.callback
package.
The following example shows 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 and a 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 With &DirectorySDKForJava;
You are ready to authenticate when you have done the following:
Determined that at least one SASL mechanism exists in common
between the server and your client environment
Implemented javax.security.auth.callback.CallbackHandler
if you might need to supply additional credentials during authentication
The following example shows 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
SASL
using the EXTERNAL mechanism with
SSL
using SASL with
&DirectorySDKForJava; includes a mechanism called EXTERNAL.
This mechanism verifies that SSL authentication has already completed before
the mechanism allows a client to connect over LDAP.
To use the EXTERNAL mechanism, do the following:
Bind to the server, and authenticate using SSL.Refer
to Connecting to a
Server Over SSL With Directory SDK for Java for details.
Call the LDAPConnection.authenticate method
as follows:
ld = new LDAPConnection();
ld.authenticate(
null, new String[]{"EXTERNAL"}, null, (CallbackHandler)null);
LDAPConnection.authenticate takes the following parameters.
dn
Authentication DN
mechanisms
List of SASL mechanisms to use for authentication
If null is specified, &DirectorySDKForJava; queries
the server for all available mechanisms.
props
Optional properties that the mechanism accepts, which include
the following:
javax.security.sasl.encryption.minimum
The minimum key length to be used during the session.
The default value is 0, 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
The client's IP address in dotted decimal format.
This value is required for KERBEROS_V4 authentication.
No default value exists.
javax.security.sasl.ip.remote
The server's IP address in dotted decimal format.
This value is required for KERBEROS_V4 authentication.
No default value exists.
javax.security.sasl.maxbuffer
The maximum size of the security layer frames.
The default is 0, meaning that the client does not
use the security layer.
javax.security.sasl.client.pkgs
A bar-separated list of package names to use when locating
a SaslClientFactory.
cbh
Instance of CallbackHandler that is
implemented in your application.
Other SASL Mechanisms
Authentication with a SASL mechanism other than EXTERNAL requires
you to implement classes for the mechanism in the client and on the server.
Further Reading About SASL
SASL is described in RFC 4422.
For a current list of registered SASL mechanisms, see http://www.iana.org/assignments/sasl-mechanisms
.