DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
Overriding Tomcat Valve To Return Extended Login Failure Status
See <a href="http://shadegrowncode.blogspot.com/2007/03/returning-login-failure-reason-in.html">Shade Grown Code</a> for more information.
ExtendedStatusSetter.java
package com.ofc.tomcat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Interface flagging that the implementing Realm can set request
* headers providing additional information about an authentication
* failure.
*
* @author Nicholas Sushkin
*/
public interface ExtendedStatusSetter
{
/**
* The request attribute under which we forward an extended failure status message
* (as an object of type String) to a login error page.
*/
public static String LOGIN_FAILURE_MESSAGE_ATTR =
"com.ofc.tomcat.LOGIN_FAILURE_MESSAGE";
public void setExtendedStatus(String username, HttpServletRequest request, HttpServletResponse response);
}
ExtendedStatusFormAuthenticator.java
package com.ofc.tomcat;
import org.apache.catalina.authenticator.Constants;
import org.apache.catalina.authenticator.FormAuthenticator;
import org.apache.catalina.Realm;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.RequestDispatcher;
/**
* Adds extended authentication failure status to tomcat FormAuthenticator.
*
* @author Nicholas Sushkin
*/
public class ExtendedStatusFormAuthenticator extends FormAuthenticator
{
/**
* Descriptive information about this implementation.
*/
protected static final String info =
"com.ofc.tomcat.ExtendedStatusFormAuthenticator/1.0";
private static Log log = LogFactory.getLog(ExtendedStatusFormAuthenticator.class);
// ------------------------------------------------------------- Properties
/**
* Return descriptive information about this Valve implementation.
*/
@Override
public String getInfo()
{
return info;
}
// ------------------------------------------------------------- Overridden behavior
/**
* Called to forward to the error page
*
* @param request Request we are processing
* @param response Response we are creating
* @param config Login configuration describing how authentication
* should be performed
*/
@Override
protected void forwardToErrorPage(Request request, Response response, LoginConfig config)
{
Realm realm = context.getRealm();
if (realm instanceof ExtendedStatusSetter)
{
log.debug("realm implements ExtendedStatusSetter, setting extended status for error page");
String username = request.getParameter(Constants.FORM_USERNAME);
((ExtendedStatusSetter) realm).setExtendedStatus(username, request.getRequest(), response.getResponse());
}
else
{
log.debug("realm does not implement ExtendedStatusSetter, NOT setting extended status for error page");
}
RequestDispatcher disp =
context.getServletContext().getRequestDispatcher
(config.getErrorPage());
try {
disp.forward(request.getRequest(), response.getResponse());
response.finishResponse();
} catch (Throwable t) {
log.warn("Unexpected error forwarding to error page", t);
}
}
}
Realm implementation will include the following
public class AccountLockoutDatasourceRealm extends DataSourceRealm implements ExtendedStatusSetter
{
// ...
public void setExtendedStatus(String username, HttpServletRequest request, HttpServletResponse response)
{
setMessage(request, "Account locked");
}
protected void setMessage(HttpServletRequest request, String message)
{
request.setAttribute(ExtendedStatusSetter.LOGIN_FAILURE_MESSAGE_ATTR, message);
}
}






Comments
Snippets Manager replied on Wed, 2008/10/08 - 5:03pm