For my web application I have written AuthenticationFilter
which validates each request to check against CSRF attacks, Browser Checks, Session Validity etc. Instead of putting multiple if else blocks I thought it can be implemented as following.
Please let me know if I can improve this.
public interface IValidator {
public void validate(Context context) throws ValidatorException;
public void handleFailure(Context context) throws Exception;
}
public class CSRFValidator implements IValidator, CWSConstants {
private final Logger LOGGER = LoggerFactory.getLogger(CSRFValidator.class);
@Override
public void validate(Context context) throws ValidatorException {
//some logic to validate request if it contains CSRF token
}
@Override
public void handleFailure(Context context) throws Exception {
context.getHttpServletResponse().sendError(HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION);
}
}
public class BrowserCheckValidator implements IValidator, CWSConstants {
private final Logger LOGGER = LoggerFactory.getLogger(CSRFValidator.class);
@Override
public void validate(Context context) throws ValidatorException {
//if request is not coming from suported browser then throw exception
}
@Override
public void handleFailure(Context context) throws Exception {
context.getHttpServletResponse().sendError(HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION);
}
}
public class AuthenticationFilter implements Filter{
private List<IValidator> requestValidators = new ArrayList<>();
public void doFilter(ServletRequest request, ServletResponse response, FilterChain fc)
throws IOException, ServletException {
Context context = new Context(httpRequest, httpResponse, session);
for (IValidator validator : requestValidators) {
try {
LOGGER.debug("Validating " + validator.getClass().getName());
validator.validate(context);
} catch (ValidatorException e) {
LOGGER.error("Error while validating " + validator.getClass().getName(), e);
validator.handleFailure(context);
return;
}
}
fc.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.debug("Initializing validators");
requestValidators.add(new CSRFValidator());
}
}
public class ValidatorException extends Exception {
private static final long serialVersionUID = 8990146478624920065L;
public ValidatorException() {
super();
}
public ValidatorException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public ValidatorException(String message, Throwable cause) {
super(message, cause);
}
public ValidatorException(String message) {
super(message);
}
public ValidatorException(Throwable cause) {
super(cause);
}
}
public final class Context {
private HttpServletRequest httpServletRequest;
private HttpServletResponse httpServletResponse;
private HttpSession httpSession;
public Context(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
HttpSession httpSession) {
this.httpServletRequest = httpServletRequest;
this.httpServletResponse = httpServletResponse;
this.httpSession = httpSession;
}
public HttpServletRequest getHttpServletRequest() {
return httpServletRequest;
}
public HttpServletResponse getHttpServletResponse() {
return httpServletResponse;
}
public HttpSession getHttpSession() {
return httpSession;
}
}
IValidator
interface name, it looks fine for me :) \$\endgroup\$