Callbacks for SASL Mechanisms

A SASL mechanism is always given the authorization id (that
specified by the "java.naming.security.sasl.authorizationId")
environment property.
All other input is supplied on-demand, that is, on request of the mechanism.

By default, the LDAP provider supplies the authentication id
and credentials by using, respectively, the
Context.SECURITY_PRINCIPAL and
Context.SECURITY_CREDENTIALS environment properties.
If a SASL mechanism requires input other than these, or if you
prefer to supply the input through a different means, then you
can define a callback handler object for the mechanism
to use. To do this, you set
the "java.naming.security.sasl.callback" environment property
to the callback handler object, as explained next.

The callback handler must be able to handle the type of callback requested
by a mechanism, so the application that creates/uses the callback handler
must have some knowledge about what the mechanism requires.
For example, in addition to the NameCallback and
PasswordCallback, the Digest-MD5 mechanism requires
also callbacks to get the realm.
The realm is obtained by using either a
javax.security.auth.callback.TextInputCallback or
javax.security.auth.callback.ChoiceCallback.

Here is an example of a callback handler
that handles NameCallback and PasswordCallback by
reading the data from Standard Input.

CRAM-MD5 by Using a Callback Handler

Here's a modified version
of the CRAM-MD5 example
that gets its password by using a callback handler instead the
Context.SECURITY_PRINCIPAL and
Context.SECURITY_CREDENTIALS
environment properties.
The CRAM-MD5 mechanism needs
the authentication id and the password as input. These are supplied by
SampleCallbackHandler.

// Set up the environment for creating the initial context
Hashtable env = new Hashtable(11);
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");
env.put(Context.SECURITY_AUTHENTICATION, "CRAM-MD5");
// Specify the callback to use for fetching the authentication id/password
env.put("java.naming.security.sasl.callback", new SampleCallbackHandler());
// Create the initial context
DirContext ctx = new InitialDirContext(env);
// ... do something useful with ctx