WebSphere (traditional): In case of container based authentication with custom user registry, when the login from web application failed, we used to find
the root cause of failure by calling:
com.ibm.websphere.security.auth.WSSubject.getRootLoginException();
The above API exists in: {Server_Root_Dir}/AppServer/plugins/com.ibm.ws.runtime_x.y.z.jar
The decompiled source-code of the method getRootLoginException() is:
public static Throwable getRootLoginException(){
return ContextManagerFactory.getInstance().getRootException();
}
WebSphere (Liberty): In case of container based authentication with custom user registry, we are not able to find
the root cause of failure of login by calling:
com.ibm.websphere.security.auth.WSSubject.getRootLoginException();
The above API exists in: {Server_Root_Dir}/lib/com.ibm.websphere.security_x.y.z.jar
It is because the decompiled source-code of the method getRootLoginException() is:
public static Throwable getRootLoginException(){
return null;
}
IBM claims that:
public static java.lang.Throwable getRootLoginException()
This convenient method returns the root login exception caught in the system login module, if one exists.
It will extract the exception from the current thread. You will get what the login module sees as the root exception. This could be a nested exception. You may need to extract exceptions from the exception returned until you get the real root exception.
Returns: A Throwable containing the root login exception. If a login exception did not occur, null will be returned.
I would like to know which API to call in WebSphere (Liberty) in order to find the root cause of failure of login.
Why WSSubject.getRootLoginException() is needed:
The custom implementation of com.ibm.websphere.security.UserRegistry requires that you validate the username and password entered by the web application user by providing your own definition of checkPassword(String userSecurityName, String passwd). Please see http://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/csec_customauth.html
If the user provides incorrect information you may throw PasswordCheckFailedException or CustomRegistryException with your message. This checkPassword(String userSecurityName, String passwd) is actually invoked by the WebSphere (traditional or Liberty) from JAAS javax.security.auth.spi.LoginModule.login() and PasswordCheckFailedException or CustomRegistryException and their messages are wrapped and javax.security.auth.login.LoginException is thrown.
In order to provide feedback to the web application user we need to get hold of the Exception thrown from javax.security.auth.spi.LoginModule.login().
The way to do this is by calling com.ibm.websphere.security.auth.WSSubject.getRootLoginException() from a servlet filter. This works fine in WebSphere (traditional) but not any more in WebSphere (Liberty). The problem is that IBM has not documented this limitation anywhere.
In traditional WAS this was resolved as APAR PM21010 a long time ago. You might want to file a PMR, especially since Brian found that this is documented as a supported API in WebSphere Liberty Profile.