339 lines
16 KiB
Plaintext
339 lines
16 KiB
Plaintext
<!--
|
|
|
|
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
Portions copyright 1999 Netscape Communications Corporation. All
|
|
Rights Reserved.
|
|
|
|
The contents of this document are subject to the terms of the
|
|
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
|
version (the "License"). You may not use this document except in
|
|
compliance with the License.
|
|
|
|
See the License for the specific language governing
|
|
permissions and limitations under the License. You can obtain
|
|
a copy of the License at
|
|
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
|
|
|
-->
|
|
<chapter id="sasl"><title>SASL Authentication With &DirectorySDKForJava;</title>
|
|
<highlights>
|
|
<para>This chapter describes the process of using a SASL mechanism to authenticate
|
|
an LDAP client to an LDAP server.</para>
|
|
<itemizedlist>
|
|
<para>This chapter covers the following topics:</para>
|
|
<listitem><para><olink targetptr="sasl-overview">Understanding SASL and Directory
|
|
SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="sasl-prepare">Preparing to Use SASL Authentication
|
|
With Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="sasl-client">Using SASL in the Client With
|
|
Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="sasl-reading">Further Reading About SASL</olink></para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</highlights>
|
|
<sect1 id="sasl-overview"><title>Understanding SASL and &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>SASL</primary>
|
|
<secondary>defined</secondary>
|
|
</indexterm>
|
|
<para>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.</para>
|
|
<para>All SASL mechanisms are registered with the Internet Assigned Numbers
|
|
Authority (IANA). Included among these mechanisms are <literal>KERBEROS_V4</literal>, <literal>
|
|
GSSAPI</literal>, 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.</para>
|
|
<para>When a client attempts to authenticate to an LDAP server with the <literal>
|
|
LDAPConnection.authenticate</literal> 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.</para>
|
|
<para>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.</para>
|
|
<para>If the server does not support any of the requested mechanisms, the
|
|
SDK returns an <classname>AuthenticationNotSupportedException</classname>.</para>
|
|
<para>If the mechanism driver requires additional authentication data from
|
|
the client, the driver sends a <classname>Callback</classname> object to the
|
|
client. To prepare for the callback, the client implements a <classname>CallbackHandler
|
|
</classname> 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 <classname>CallbackHandler</classname> object
|
|
with <classname>Callback</classname> objects for each item to be processed.
|
|
The <classname>CallbackHandler</classname> then determines how to proceed.</para>
|
|
<para>&DirectorySDKForJava; includes a package, <literal>com.netscape.sasl</literal>,
|
|
that contains the code necessary to perform all of the steps involved in SASL
|
|
authentication.</para></sect1>
|
|
<sect1 id="sasl-prepare"><title>Preparing to Use SASL Authentication With &DirectorySDKForJava;</title>
|
|
<itemizedlist>
|
|
<para>Before performing SASL authentication, you must do the following:</para>
|
|
<listitem><para>Ensure that your LDAP server supports at least one SASL mechanism
|
|
</para></listitem>
|
|
<listitem><para>Ensure that your client environment supports at least one
|
|
SASL mechanism supported by the server</para></listitem>
|
|
</itemizedlist>
|
|
<sect2 id="sasl-prepare-server"><title>SASL Support on the Server</title>
|
|
<indexterm>
|
|
<primary>SASL</primary>
|
|
<secondary>server-side requirements</secondary>
|
|
</indexterm>
|
|
<para>&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.</para>
|
|
<itemizedlist>
|
|
<para>If you write your own plug-in, your plug-in uses a registered SASL mechanism
|
|
to do the following:</para>
|
|
<listitem><para>Get information from a SASL bind request.</para></listitem>
|
|
<listitem><para>Create and send a SASL bind response back to the client.</para>
|
|
<para>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.</para></listitem>
|
|
</itemizedlist>
|
|
</sect2>
|
|
<sect2 id="sasl-prepare-client"><title>SASL Support on the Client</title>
|
|
<indexterm>
|
|
<primary>SASL</primary>
|
|
<secondary>client-side requirements</secondary>
|
|
</indexterm>
|
|
<para>To authenticate over SASL, you must have a mechanism in your SASL client
|
|
package. If you have obtained a <classname>ClientFactory</classname> class
|
|
that can produce a SASL mechanism that your server supports, you can name
|
|
its package in your code.</para>
|
|
<itemizedlist>
|
|
<para>This option can be performed in one of two ways:</para>
|
|
<listitem><para>Request a SASL client. Specify the package in the <property>javax.security.sasl.client.pkgs
|
|
</property> property of its <classname>Hashtable</classname>.</para></listitem>
|
|
<listitem><para>Set the package as the default factory for the session with
|
|
the <literal>Sasl.setSaslClientFactory</literal> method.</para></listitem>
|
|
</itemizedlist>
|
|
<para>For example, you might have a class, <classname>mysecurity.sasl.ClientFactory
|
|
</classname>, capable of producing a <classname>SaslClient</classname> object
|
|
for one or more mechanisms. You could then write either of the two following
|
|
bits of code:</para>
|
|
<programlisting>Hashtable props = new Hashtable();
|
|
props.put("javax.security.sasl.client.pkgs", "mysecurity.sasl");
|
|
ld.authenticate(dn, props, cbh);</programlisting>
|
|
<programlisting>Sasl.setSaslClientFactory (new mysecurity.sasl.ClientFactory());
|
|
ld.authenticate(dn, props, cbh);</programlisting>
|
|
<para>The parameters used have the following descriptions:</para>
|
|
<variablelist>
|
|
<varlistentry><term><parameter>dn</parameter></term>
|
|
<listitem><para>Authentication DN</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><parameter>props</parameter></term>
|
|
<listitem><para>Optional properties that the mechanism accepts</para>
|
|
<para>Refer to <olink type="auto-generated" targetptr="sasl-client-external">Using
|
|
the External Mechanism</olink> for details.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><parameter>cbh</parameter></term>
|
|
<listitem><para>Instance of <classname>CallbackHandler</classname> that is
|
|
implemented in your application</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect2>
|
|
<sect2 id="sasl-prepare-callback"><title>Implementing <literal>javax.security.auth.callback
|
|
</literal></title>
|
|
<indexterm>
|
|
<primary>authentication</primary>
|
|
<secondary>implementing SASL callbacks</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>callbacks</primary>
|
|
<secondary>implementing for SASL</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>SASL</primary>
|
|
<secondary>implementing callbacks</secondary>
|
|
</indexterm>
|
|
<para>Some SASL mechanisms require additional credentials during the authentication
|
|
process. To provide this additional information, your SASL client might need
|
|
to implement <classname>Callback</classname> objects and a <classname>CallbackHandler
|
|
</classname> to list credentials. <classname>Callback</classname> and <classname>
|
|
CallbackHandler</classname> are part of the <literal>javax.security.auth.callback
|
|
</literal> package.</para>
|
|
<para>The following example shows <classname>Callback</classname> and <classname>
|
|
CallbackHandler</classname> implementations.</para>
|
|
<programlisting>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;
|
|
}</programlisting>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="sasl-client"><title>Using SASL in the Client With &DirectorySDKForJava;</title>
|
|
<itemizedlist>
|
|
<para>You are ready to authenticate when you have done the following:</para>
|
|
<listitem><para>Determined that at least one SASL mechanism exists in common
|
|
between the server and your client environment</para></listitem>
|
|
<listitem><para>Implemented <classname>javax.security.auth.callback.CallbackHandler
|
|
</classname> if you might need to supply additional credentials during authentication
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
<para>The following example shows how to use SASL in an application:</para>
|
|
<programlisting>Hashtable props = new Hashtable();
|
|
props.put("javax.security.sasl.client.pkgs", "mysecurity.sasl");
|
|
ld.authenticate(dn, props, new SampleCallbackHandler());</programlisting>
|
|
<sect2 id="sasl-client-external"><title>Using the <literal>External</literal> Mechanism
|
|
</title>
|
|
<indexterm>
|
|
<primary>SASL</primary>
|
|
<secondary>using the EXTERNAL mechanism with</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>SSL</primary>
|
|
<secondary>using SASL with</secondary>
|
|
</indexterm>
|
|
<para>&DirectorySDKForJava; includes a mechanism called <literal>EXTERNAL</literal>.
|
|
This mechanism verifies that SSL authentication has already completed before
|
|
the mechanism allows a client to connect over LDAP.</para>
|
|
<orderedlist>
|
|
<para>To use the <literal>EXTERNAL</literal> mechanism, do the following:</para>
|
|
<listitem><para>Bind to the server, and authenticate using SSL.</para><para>Refer
|
|
to <olink type="auto-generated" targetptr="ssl-connecting">Connecting to a
|
|
Server Over SSL With Directory SDK for Java</olink> for details.</para>
|
|
</listitem>
|
|
<listitem><para>Call the <literal>LDAPConnection.authenticate</literal> method
|
|
as follows:</para>
|
|
<programlisting>ld = new LDAPConnection();
|
|
ld.authenticate(
|
|
null, new String[]{"EXTERNAL"}, null, (CallbackHandler)null);</programlisting>
|
|
<para><literal>LDAPConnection.authenticate</literal> takes the following parameters.
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry><term><parameter>dn</parameter></term>
|
|
<listitem><para>Authentication DN</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><parameter>mechanisms</parameter></term>
|
|
<listitem><para>List of SASL mechanisms to use for authentication</para>
|
|
<para>If <literal>null</literal> is specified, &DirectorySDKForJava; queries
|
|
the server for all available mechanisms.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><parameter>props</parameter></term>
|
|
<listitem><para>Optional properties that the mechanism accepts, which include
|
|
the following:</para>
|
|
<variablelist>
|
|
<varlistentry><term><property>javax.security.sasl.encryption.minimum</property></term>
|
|
<listitem><para>The minimum key length to be used during the session.</para>
|
|
<para>The default value is <literal>0</literal>, no session protection. A
|
|
value of <literal>1</literal> enables integrity protection only.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><property>javax.security.sasl.encryption.maximum</property></term>
|
|
<listitem><para>The maximum key length to be used during the session.</para>
|
|
<para>The default value is <literal>256</literal>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><property>javax.security.sasl.server.authentication</property></term>
|
|
<listitem><para>A boolean value.</para>
|
|
<para><literal>true</literal> if a server must authenticate to the client.
|
|
The default value is <literal>false</literal>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><property>javax.security.sasl.ip.local</property></term>
|
|
<listitem><para>The client's IP address in dotted decimal format.</para>
|
|
<para>This value is required for <literal>KERBEROS_V4</literal> authentication.
|
|
No default value exists.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><property>javax.security.sasl.ip.remote</property></term>
|
|
<listitem><para>The server's IP address in dotted decimal format.</para>
|
|
<para>This value is required for <literal>KERBEROS_V4</literal> authentication.
|
|
No default value exists.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><property>javax.security.sasl.maxbuffer</property></term>
|
|
<listitem><para>The maximum size of the security layer frames.</para>
|
|
<para>The default is <literal>0</literal>, meaning that the client does not
|
|
use the security layer.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><property>javax.security.sasl.client.pkgs</property></term>
|
|
<listitem><para>A bar-separated list of package names to use when locating
|
|
a <classname>SaslClientFactory</classname>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry><term><parameter>cbh</parameter></term>
|
|
<listitem><para>Instance of <classname>CallbackHandler</classname> that is
|
|
implemented in your application.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</listitem>
|
|
</orderedlist>
|
|
</sect2>
|
|
<sect2 id="sasl-client-other"><title>Other SASL Mechanisms</title>
|
|
<para>Authentication with a SASL mechanism other than <literal>EXTERNAL</literal> requires
|
|
you to implement classes for the mechanism in the client and on the server.</para>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="sasl-reading"><title>Further Reading About SASL</title>
|
|
<para>SASL is described in <ulink url="http://www.ietf.org/rfc/rfc4422.txt"
|
|
type="text_url">RFC 4422</ulink>.</para>
|
|
<para>For a current list of registered SASL mechanisms, see <ulink
|
|
url="http://www.iana.org/assignments/sasl-mechanisms" type="url">http://www.iana.org/assignments/sasl-mechanisms
|
|
</ulink>.</para></sect1>
|
|
</chapter>
|