Find the root cause login exception from a JAAS login

If you get a LoginException after issuing the LoginContext.login() API, you can find the root cause exception from the configured user registry. In the login modules, the registry exceptions are wrapped by a com.ibm.websphere.security.auth.WSLoginFailedException. This exception has a getCause() method that allows you to pull out the exception that was wrapped.

Note: You are not always guaranteed to get an exception of type WSLoginFailedException, but you should note that most of the exceptions generated from the user registry show up here.

The following is a LoginContext.login() API example with associated catch block. WSLoginFailedException has to be casted to com.ibm.websphere.security.auth.WSLoginFailedException if you want to issue the getCause() API.

Note: The determineCause() example below can be used for processing CustomUserRegistry exception types.

try {
  lc.login(); 
} catch (LoginException le) {
  // Drill down through the exceptions as they might cascade through the runtime.
  Throwable root_exception = determineCause(le);
  
  // Now you can use "root_exception" to compare to a particular exception type.
  // For example, if you have implemented a CustomUserRegistry type, you would know
  // what to look for here.
}

/* Method used to drill down into the WSLoginFailedException to find the
 * "root cause" exception */
public Throwable determineCause(Throwable e) {
  Throwable root_exception = e, temp_exception = null;

  // Keep looping until there are no more embedded WSLoginFailedException
  // or WSSecurityException exceptions.
  while (true) {
    if (e instanceof com.ibm.websphere.security.auth.WSLoginFailedException) {                
      temp_exception =
         ((com.ibm.websphere.security.auth.WSLoginFailedException) e).getCause();
    }
    else if (e instanceof com.ibm.websphere.security.WSSecurityException) {
      temp_exception =
         ((com.ibm.websphere.security.WSSecurityException) e).getCause();
    }
    else if (e instanceof com.ibm.ws.security.registry.os400.OS400RegistryException) {
      // get OS400 specific error code, if configured
      System.out.println ("Error code from OS400 exception: "
         + ((com.ibm.ws.security.registry.os400.OS400RegistryException)e).getErrorCode());
      return e;
    }
    else if (e instanceof javax.naming.NamingException) {
      // check for Ldap embedded exception
      temp_exception = ((javax.naming.NamingException)e).getRootCause();
    }
    else if (e instanceof your_custom_exception_here) {
      // your custom processing here, if necessary
    }
    else {
      // This exception is not one of the types we are looking for, return now.
      // This is the root from the WebSphere perspective
      return root_exception;
    }
                 
    if (temp_exception != null) {
      // We have an exception, let's go back and see if this has another
      // one embedded within it.
      root_exception = temp_exception;
      e = temp_exception;
      continue;
    } 
    else  {
      // We finally have the root exception from this call path,
      // this has to occur at some point.
      return root_exception;
    }
  }
}