I'm having some difficulty with servlet and filter lifecycles. The intention here is to use the front controller pattern with a simple login; authentication is accomplished with the filter.
Am I passing the auth
token in a rational way?
The login.jsp
page:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>login</title>
</head>
<body>
<img src="${sessionScope.auth.duke}">
my name is ${requestScope.controller.myName}, ${requestScope.controller.myId}, what's yours?
<form name="user_name_form" action="controller" method="POST">
login: <input type="text" name="login" value="" size='20' />
<p>
<input type="submit">
</p>
</form>
${sessionScope.auth.greeting}
<p></p>
<p></p>
<p></p>
<p></p>
</body>
</html>
The filter (as bare-bones as possible):
package net.bounceme.dur.webapp.filter;
import net.bounceme.dur.webapp.tokens.AuthenticationToken;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
@WebFilter(
filterName = "authenticationFilter",
description = "authentication",
urlPatterns = "/*",
initParams = {
@WebInitParam(name = "1", value = "bart"),
@WebInitParam(name = "2", value = "homer")})
public class AuthenticationFilter implements Filter {
private static final Logger log = Logger.getLogger(AuthenticationFilter.class.getName());
private FilterConfig filterConfig = null;
private final Map<String, String> mapOfUsers = new HashMap<>();
private final AuthenticationToken token = new AuthenticationToken();
private final String className = AuthenticationFilter.class.getName();
private Map<String, String> parameters = new HashMap<>();
private Map<String, String> users = new HashMap<>();
private boolean auth = false;
private String contextPath;
public AuthenticationFilter() {
}
private void doBeforeProcessing(ServletRequest request, ServletResponse response) throws IOException, ServletException {
log.fine("do before processing.."); //init?
}
private void doAfterProcessing(ServletRequest request, ServletResponse response) throws IOException, ServletException {
log.fine("do after processing"); //add image here?
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info(className + "do filter..");
token.setToken((HttpServletRequest) request);
chain.doFilter(request, response);
log.info(className + "..do filter");
}
public FilterConfig getFilterConfig() {
return (this.filterConfig);
}
public void setFilterConfig(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) {
log.info(className + "\tinit..");
this.filterConfig = filterConfig;
if (filterConfig != null) {
log.fine("SessionCheckFilter:Initializing filter");
} else {
log.warning("null filterConfig");
}
String context = filterConfig.getServletContext().getServletContextName();
String path = filterConfig.getServletContext().getContextPath();
contextPath = "http://localhost:8080" + context + path;
String duke = contextPath + "/duke.gif";
token.setDuke(duke);
token.initFilterConfig(filterConfig);
log.info(token.toString());
log.info(className + "\t..init");
}
@Override
public String toString() {
return token.toString();
}
private void sendProcessingError(Throwable t, ServletResponse response) {
log.fine("send processing error");
String stackTrace = getStackTrace(t);
if (stackTrace != null && !stackTrace.equals("")) {
try {
response.setContentType("text/html");
try (PrintStream ps = new PrintStream(response.getOutputStream()); PrintWriter pw = new PrintWriter(ps)) {
pw.print("<html>\n<head>\n<title>Error</title>\n</head>\n<body>\n"); //NOI18N
pw.print("<h1>The resource did not process correctly</h1>\n<pre>\n");
pw.print(stackTrace);
pw.print("</pre></body>\n</html>"); //NOI18N
}
response.getOutputStream().close();
} catch (Exception ex) {
}
} else {
try {
try (PrintStream ps = new PrintStream(response.getOutputStream())) {
t.printStackTrace(ps);
}
response.getOutputStream().close();
} catch (Exception ex) {
}
}
}
public static String getStackTrace(Throwable t) {
String stackTrace = null;
try {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
pw.close();
sw.close();
stackTrace = sw.getBuffer().toString();
} catch (Exception ex) {
}
log.warning(stackTrace);
return stackTrace;
}
}
The token (as heavy as possible):
package net.bounceme.dur.webapp.tokens;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.servlet.FilterConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class AuthenticationToken implements MyToken {
private static final Logger log = Logger.getLogger(AuthenticationToken.class.getName());
private Map<String, MyRoles> mapOfUsers;
private String duke = "duke..";
private String login = "nemo";
private String className = AuthenticationToken.class.getName();
private boolean auth = false;
private String greeting = "";
private Map<String, String> users = new HashMap<>();
private Map<String, String> parameters = new HashMap<>();
private String contextPath;
public AuthenticationToken() { //would like to make private
log.info(AuthenticationToken.class.getName() + "\tnew..");
}
public void initFilterConfig(FilterConfig filterConfig) {
log.info(className + "\tinitFilterConfig..");
Enumeration parameterNames = filterConfig.getInitParameterNames();
users = new HashMap<>(); //?
String name = null;
String val = null;
while (parameterNames.hasMoreElements()) {
name = parameterNames.nextElement().toString();
val = filterConfig.getInitParameter(name);
users.put(name, val);
}
log.info(className + "\n" + users);
log.info(className + "\t..initFilterConfig");
}
private void initParams(HttpServletRequest request) {
log.info(className + "\tinitParams..");
parameters = new HashMap<>(); //?
Enumeration<String> params = request.getParameterNames();
String name = null;
String val = null;
while (params.hasMoreElements()) {
name = params.nextElement();
val = request.getParameter(name);
parameters.put(name, val);
}
log.info(className + "\n" + parameters);
log.info(className + "\t..initParams");
}
public void setToken(HttpServletRequest request) {
log.info(className + "\tsetToken..");
initParams(request);
String login = null;
if (parameters.containsKey("login")) {
login = parameters.get("login").toLowerCase();
setLogin(login);
if (users.containsValue(login)) {
auth = true;
setGreeting("welcome " + login + " you've been authorized.");
String image = contextPath + "/" + login + ".gif";
} else {
auth = false;
setGreeting("welcome " + login);
String image = contextPath + "/duke.gif";
}
} else {
auth = false;
String image = contextPath + "/duke.gif";
}
HttpSession session = request.getSession(false);
if (session != null) {
session.setAttribute("auth", this); //??
}
log.info(toString());
log.info(className + "\t..setToken");
}
public String getDuke() {
return duke;
}
public void setDuke(String duke) {
this.duke = duke;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public boolean isAuth() {
return auth;
}
public void setAuth(boolean auth) {
this.auth = auth;
}
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
@Override
public String toString() {
return duke;
}
}
(The only reason all users get the duke gif is because I was having trouble copying gif's into the web folder...I'll fix that down the road. Each user will have their own gif: bart.gif, homer.gif, etc.)
full code: https://github.com/THUFIR/WebApplication