Previous | Next | Trail Map | Tips for LDAP Users | Referrals

Manually Following Referrals

If you set the Context.REFERRAL(in the API reference documentation) ("java.naming.referral") environment property to "throw", then each referral encountered results in a ReferralException(in the API reference documentation). A ReferralException contains referral information, which is information that describes the referral (such as a list of URLs), and a referral context, which is the context that the referral refers to. Here are the steps that a program usually follows when manually handling referrals:
  1. Catch the exception.
  2. Examine the referral information using ReferralException.getReferralInfo()(in the API reference documentation) . For example, ask the user whether the referral should be followed.
  3. If the referral is to be followed, get the referral context using ReferralException.getReferralContext()(in the API reference documentation) and reinvoke the original context method using the same arguments supplied to the original invocation.
  4. If the referral is not to be followed, invoke ReferralException.skipReferral()(in the API reference documentation) . If this method returns true, then invoke ReferralException.getReferralContext() to continue. When you invoke a context method on the result, it will again throw a ReferralException, and the process repeats from Step 1. If the method returns false, there are no more referrals and this procedure can be terminated.

Here's an example:

// Set referral property to throw ReferralException
env.put(Context.REFERRAL, "throw");

// Create initial context
DirContext ctx = new InitialDirContext(env);

// Set controls for performing subtree search
SearchControls ctls = new SearchControls();
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

while (true) {
    try {
        // Perform search
        NamingEnumeration answer = ctx.search("", "(objectclass=*)", ctls);

        // Print the answer
        while (answer.hasMore()) {
  	    System.out.println(">>>" + ((SearchResult)answer.next()).getName());
        }
        break;  // search completes with no more referrals

    } catch (ReferralException e) {

        if (! followReferral(e.getReferralInfo())) {
   	    if (! e.skipReferral()) {
  	        break; // no more referrals to process
	    }
        }
        // point to the new context
        ctx = (DirContext) e.getReferralContext();
    }
}
For methods that return an enumeration, such as Context.list()(in the API reference documentation) and DirContext.search()(in the API reference documentation) , you must place the try/catch for ReferralException around both the initial invocation and the while loop that iterates through the results. When the ReferralException is thrown, the existing enumeration becomes invalid and you must reinvoke the original context method to get a new enumeration. Notice also that the outer while loop encloses both the method invocation on the context and the iteration of the results.

Authenticating to a Referral Context

By default, when you invoke ReferralException.getReferralContext(), the LDAP provider uses the original context's environment properties, including its security-related properties, to create a connection to the referred server. Sometimes, upon examining the referral information, you might want to follow the referral using different authentication information.

You can do this by using the LDAP provider directly:

import com.sun.jndi.ldap.LdapReferralException;
...
} catch (LdapReferralException e) {
...
    env.put(Context.SECURITY_PRINCIPAL, "newuser");
    env.put(Context.SECURITY_CREDENTIALS, "newpasswd");
    ctx = e.getReferralContext(env);
}
The ability to do this using ReferralException is planned for a future release of the JNDI.


Previous | Next | Trail Map | Tips for LDAP Users | Referrals