Jan
Jan

Reputation: 87

Tomcat 9 access log does not show the username (i.e. %u) logged-in via HttpSession + JSP + Servlet

I want to include the username to localhost_access_log in Tomcat 9. My LoginServlet is:

if(r1.next() && username.equals(r1.getString(1))  && ...) {         
            HttpSession session = request.getSession();
            session.setAttribute("username", username);
            //setting session to expiry in 120 mins
            session.setMaxInactiveInterval(120*60);
            response.sendRedirect("system.jsp");
            // Close the database connections
            conn.close();
        } else ...

The LoginFilter is as follows:

@WebFilter( urlPatterns = {"/LoginFilter",  "/system.jsp", "/login.jsp" })
public class LoginFilter implements Filter {

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    HttpSession session = request.getSession(false);
    String loginURI = request.getContextPath() + "/login.jsp";
    boolean loggedIn = session != null && session.getAttribute("username") != null;
    boolean loginRequest = request.getRequestURI().equals(loginURI);
    
    if(loginRequest) {
        if (loggedIn) {
            response.sendRedirect(request.getContextPath() + "/system.jsp");
        }
        else {
            // if user has not logged in
            chain.doFilter(request, response);
        }} else...

Everything works fine.

For logging, in server.xml, the pattern is:

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%{X-Forwarded-For}i %l %u %t &quot;%r&quot; %s %b" />

The localhost_access_log shows IP address, etc. except the user name (just shows a -). What to do to include the logged-in username here (servlet + HttpSession + jsp). Is it possible? Any alternative solutions?

Thank you.

Upvotes: 1

Views: 1050

Answers (1)

Piotr P. Karwasz
Piotr P. Karwasz

Reputation: 16185

The pattern %u is empty, because the user is not authenticated according to Tomcat (cf. Authentication). You can leave your LoginServlet as it is and use the %{username}s placeholder instead of %u (cf. Access Log Valve).

However you might consider authentication methods provided by servlet containers. Tomcat has certainly a Realm implementation that suits your needs, e.g. the DataSourceRealm. Therefore you can:

  1. Configure in the META-INF/context.xml file a default Realm, so that most users need to just configure a datasource. Those with more specific needs can override the context file and configure an entirely different source of credentials,
  2. Replace the code in your LoginServlet with:
try {
  request.login(username, password);
} catch (ServletException e) {
  // deal with an authentication failure
  ...
  return;
}
final HttpSession session = request.getSession();
// setting session to expiry in 120 mins
session.setMaxInactiveInterval(120*60);
response.sendRedirect("system.jsp");
  1. To test if a request is authenticated use request.getRemoteUser() != null.

Upvotes: 2

Related Questions