Performing Operations on the Authenticated Context

Some authentication schemes and LDAP servers require some operation to be performed on the created DirContext instance for the actual authentication to occur. You should test and make sure how your server setup and authentication schemes behave; failure to do so might result in that users will be admitted into your system regardless of the DN/credentials supplied. This is a naïve implementation of an authenticate method where a hard-coded lookup operation is performed on the authenticated context:

public boolean authenticate(String userDn, String credentials) {
  DirContext ctx = null;
  try {
    ctx = contextSource.getContext(userDn, credentials);
    // Take care here - if a base was specified on the ContextSource
    // that needs to be removed from the user DN for the lookup to succeed.
    ctx.lookup(userDn);    
    return true;
  } catch (Exception e) {
    // Context creation failed - authentication did not succeed
    logger.error("Login failed", e);
    return false;
  } finally {
    // It is imperative that the created DirContext instance is always closed
    LdapUtils.closeContext(ctx);
  }
}

It would be better if the operation could be provided as an implementation of a callback interface, thus not limiting the operation to always be a lookup. Spring LDAP 1.3.0 introduced the callback interface AuthenticatedLdapEntryContextCallback and a few corresponding authenticate methods:

This opens up for any operation to be performed on the authenticated context:

Example 10.2. Performing an LDAP operation on the authenticated context using Spring LDAP.

AuthenticatedLdapEntryContextCallback contextCallback = new AuthenticatedLdapEntryContextCallback() {
  public void executeWithContext(DirContext ctx, LdapEntryIdentification ldapEntryIdentification) {
    try {
      ctx.lookup(ldapEntryIdentification.getRelativeDn());
    }
    catch (NamingException e) {
      throw new RuntimeException("Failed to lookup " + ldapEntryIdentification.getRelativeDn(), e);
    }
  }
};

ldapTemplate.authenticate("", "(uid=john.doe)", "secret", contextCallback));