views:

266

answers:

3

I am working on a small webapp for fun, using just Java Servlets at the moment. I have two pages, test1 and test2. At the moment I am creating a new session in test1 like this:

    HttpSession session = request.getSession(true);
    if (session.isNew() == false) {
        session.invalidate();
        session = request.getSession (true);
    }

In test2 I am retrieving the session like so:

    HttpSession session = request.getSession(false);
    if (session == null) {
        throw new ServletException ("No session.");
    }

So the problem is that if I go to test2 first, I am always getting a valid session because the browser creates one. I want to restrict the flow from test1 to test2 so that I have to go to test1 first. My plan is to eventually create a login page that will create the session, but the problem I am seeing here would still be present.

How should I handle this? I would like any ideas to not include 3rd party libraries. I'm doing this as a learning exercise.

Thanks!

A: 

If you want to restrict the flow to ensure that test1 comes before test2, have test1 put an attribute value in the session that says it's been visited, and test for that attribute value in test2. If the value is not there, have test2 redirect to test1.

In test1, do this:

HttpSession session = request.getSession();
session.setAttribute("test1",true);

Then, in test2, you can do this:

HttpSession session = request.getSession();
if (session.getAttribute("test1") == null){
    response.sendRedirect("test1");
    return;
}
Spike Williams
+3  A: 

This makes no sense. Forget the request.getSession(boolean). Just get the session by request.getSession() and never worry about the nullness/validness.

If you want to pass data through session attributes, then just do in test1:

request.getSession().setAttribute("test", "foo");

and in test2 (which is of course requested in the same session after test1):

String test = (String) request.getSession().getAttribute("test"); // Returns "foo".

Edit: As to using the session to check the logged-in User, just do something like in the login code:

User user = userDAO.find(username, password);
if (user != null) {
    request.getSession().setAttribute("user", user);
} else {
    // Show error?
}

and then in a Filter which is mapped on a url-pattern which represents the restricted area, just check if the User is present or not:

if (((HttpServletRequest) request).getSession().getAttribute("user") != null) {
    chain.doFilter(request, response); // Just continue.
} else {
    ((HttpServletResponse) response).sendRedirect("login"); // Not logged-in, redirect to login page.
}

and when you logout, you just remove the User from the session:

request.getSession().removeAttribute("user");

// Or, more drastically:
request.getSession().invalidate();

Alternatively you can also take a look for declarative Container Managed Security with help of some simple entries in web.xml and the server.xml. This way you don't need to hassle with login/filter logic yourself.

BalusC
I'm not looking at just passing data back and forth, but using it as a security mechanism. Perhaps I am using the session wrong entirely?
Casey
I updated the answer accordingly.
BalusC
Thanks. That is what I am trying to do.
Casey
So to make this easier, I should probably put all of my "restricted" content into a sub source folder, that way I can apply the filter to the whole thing.
Casey
Exactly :) You can for example use `url-pattern` of `/protected/*`, `/secured/*`, `/admin/*`, etc and place the content there. That's also less or more the way container managed security is supposed to work. Good luck.
BalusC
+2  A: 

A session is just a basket that starts out empty. The concept of whether a user is authenticated or not is separate from whether or not the user has a session.

JEE and the servlet specifications handle all the login stuff for you, redirecting to login pages and so on. Read up on the built-in capabilities of JEE. Maybe start here.

djna
Thanks for the link, I am definitely going to read up on this.
Casey