0

Prerequisites:

Tomcat. Webbapplication. When user goes to page, without anything fancy, he lands on index.jsp, since I have no welcome files in web.xml. index,jsp has a form which submits to Login Servlet, which checks if "user is ok". Basically if he is allowed in, otherwise he gets redirected. If he is authorized he gets a name using session.setAttribute("name", name); and then gets redirected to AdminPage.html. AdminPage.html uses JQuery and AJAX calls to a Servlet called AdminController. All this worked nice and dandy. I made a Filter just in case (If someone tries to POST directly to AdminController without being signed in), that stops calls to AdminController if the user is not logged in, that is, if session OR name is null. Filter is called AdminPageFilter. Also worked as expected.

Now if a user opens a new tab to the webapp, he should not have to log in again if he already is logged in in another tab. So I chose to make a PageLoginFilter. It checks if there is a session and name, if there is then redirect to AdminPage.html. If NOT, then user gets redirected to index, which has a form, that submits to Login Servlet etc... as above mentioned.

I also made a Logout Servlet. It gets called by clicking a link in AdminPage, and it basically first makes name null, then invalidates session, and it redirects to index.jsp.

Problem:

If user opens an additional tab, but then closes both. I.e closes browser entirely. When they then go back to the webapp, there should be no session and they should have to log in again to get to AdminPage.html But instead they are presented with the page straight away! Id doesnt even go through LoginPageFilter as far as I can tell through system printouts!

Sure, they cant DO anything because all the calls to AdminController are blocked by AdminPageFilter, but still. It seems to me like the browser somehow remembers where to go, and that LoginPageFilter gets sidestepped altogether as soon as user opens new tab when logged in, closes window and then starts over.

  1. I open new window log in and get redirected to AdminPage.html if correct password
  2. open a new tab in same window I also see a view of AdminPage.html as supposed
  3. I close all tabs and entire browser window, session should be null, reopen, go to webapp, immediately shown AdminPage.html :-(

use case flow that makes problem emerge

LoginPageFilter:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("going through PageLoginFilter?");
           HttpServletRequest req = (HttpServletRequest) request;
           HttpSession session = req.getSession(false);

           if(session == null) {
               System.out.println("session is null, must be new user");
               chain.doFilter(request, response);
           }
           else {
               System.out.println("session is there, must have opened another tab");
               request.getRequestDispatcher("/WEB-INF/AdminPage.html").forward(request, response);
           }

    }

AdminPageFilter:

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        HttpSession session = req.getSession(false);
        
        if (session == null || session.getAttribute("name") == null) {
            System.out.println(session); 
            System.out.println("session or name is NULL");
            String a = req.getRemoteAddr();
            String b = req.getRemoteHost();
            String c = req.getRemoteUser();
            int d = request.getRemotePort();
            Logger.log("Rejected User Addr: " + a + " Host: " + b + " User: " + c + " Port: " + d);
            request.getRequestDispatcher("Rejected.html").forward(request, response);
        } else {
            Logger.log("passing request throguh Filter to AdminController");
            chain.doFilter(req, res); // Logged-in user found, so just continue request.
        }

    }

web.xml

    <filter>
        <display-name>AdminPageFilter</display-name>
        <filter-name>AdminPageFilter</filter-name>
        <filter-class>application.AdminPageFilter</filter-class>
    </filter>
    <filter>
        <display-name>LoginPageFilter</display-name>
        <filter-name>LoginPageFilter</filter-name>
        <filter-class>application.LoginPageFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AdminPageFilter</filter-name>
        <url-pattern>/AdminPageFilter</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>AdminPageFilter</filter-name>
        <servlet-name>AdminController</servlet-name>
    </filter-mapping>
        <filter-mapping>
        <filter-name>AdminPageFilter</filter-name>
        <servlet-name>/WEB-INF/AdminPage.html</servlet-name>
    </filter-mapping>
    <filter-mapping>
        <filter-name>LoginPageFilter</filter-name>
        <url-pattern>/index.jsp</url-pattern>
    </filter-mapping>

And here is the Logout Servlet just in case. But I feel it is not the problem because closing the browser should remove the session and the problem persist wheter I hit Logout or not. It just "automagically" remembers AdminPage.html somehow. One way to get to loginpage index.jsp is by clearing browser memory or by waiting a while before step 3, before opening a new window, then you are "greeted" with a login page again.

public class Logout extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    public Logout() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("logging the fuck out");
        request.getSession().setAttribute("name", null);
        request.getSession().invalidate();
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

Own tries:

Read these links: how can i prevent a user from directly accessing a pages if not authenticated?

Session Tracking using J2EE

How can I handle/restrict user-access to servlets & jsp's?

https://stackoverflow.com/tags/servlet-filters/info

Java Filter to redirect users who are not logged in to login page

I have read and reread my code several times and really cant se anything wrong. Seems in step 3 LoginPageFilter gets completely sidestepped. But AdminPageFilter should catch it since it does indicate through the printout that session is indeed null, so It should redirect. I tried response.sendRedirect, i tried through RequestDispatcher. I looked at and tried different approaches in web.xml. I guess you can see these are quite stupid attempts, and I guess its because of frustration building up and Im pretty much sick of thinking about it by now. I also tried the approach of redoing it alltoghether.

Im thinking I hit that mental point where I just cant see the mistake unless someone points it out for me. Hopefully one of you guys can do that. I really want to solve this with Filters, in case you wonder.

Thanks

Redaction:

Possible solution:

After making minimal reproducable code a second time. I noticed browser really did seem to use an old cached, not up to date version, that it showed. So I Googled for: stop browser from showing outdated html. which eventually led me to:

https://stackoverflow.com/a/2068407/7989121

I'm leaving the question as is, since the search tags are completely different for that post, for those that like me thought it has to do with back end code only (well as the answer suggests, it kind of does), and did not search for the correct things, when it actually is about nudging the browser towards the desired behaviour.

brat
  • 349
  • 3
  • 11

0 Answers0