0

I need to get current session Id without hitting the session (to give it a chance to expire).

I've used Cookies from Servlet code in order keep the session not-touched and then make the session expires after its timeout time.

I am using the following code:

public static String getSessionId(HttpServletRequest request)
{
    String sessionId = "";
    String logMsg = "";
    if (request != null)
    {
        String sessionTimeout = PropertiesReader.SESSION_TIMEOUT_SCHEMA;
        if (sessionTimeout != null && SessionHelper.SESSION_TIMEOUT_FIXED.equalsIgnoreCase(sessionTimeout))
        {
            logMsg = "FIXED: Getting SessionId from Cookies with activating the session";
            Cookie[] cookies = request.getCookies();
            if (cookies != null)
            {
                for (Cookie cook : cookies)
                {
                    if ("JSESSIONID".equalsIgnoreCase(cook.getName()))
                    {
                        sessionId = cook.getValue();
                        break;
                    }
                }
            }
        } else
        {
            logMsg = "PER_USAGE: Getting SessionId from Session";
            sessionId = request.getSession(false) != null ? request.getSession(false).getId() : "";
        }
    }else
    {
        logMsg = "Request object is null";
    }

    logger.info(logMsg + ", sessionId=" + sessionId);

    return sessionId;
}

One one OC4J app server, it works fine. although on another oc4j server, the code of accessing cookies makes the session keep active and don't timeout!

EDIT:

I really stucked!, I've trying to place afilter to remove the JSESSIONID cookie and remove all cookies from the HttpServletRequest, but when I call getSession(false) on the request passed to the servlet, I got a valid Session!

class CookieRemovalHttpServletRequestWrapper extends HttpServletRequestWrapper
    {
        public static final String COOKIE_HEADER = "cookie";
        public static final String JSESSIONID = "JSESSIONID";

        public CookieRemovalHttpServletRequestWrapper(HttpServletRequest request)
        {
            super(request);
        }

        @Override
        public String getHeader(String name)
        {
            if (COOKIE_HEADER.equalsIgnoreCase(name))
            {
                return "";
            }
            return super.getHeader(name);
        }

        @Override
        public Enumeration getHeaderNames()
        {
            Enumeration e = super.getHeaderNames();
            List l = new ArrayList();
            while (e.hasMoreElements())
            {
                String headerName = (String) e.nextElement();
                if (!COOKIE_HEADER.equalsIgnoreCase(headerName))
                {
                    l.add(headerName);
                }
            }

            return Collections.enumeration(l);
        }

        @Override
        public Enumeration getHeaders(String name)
        {
            if (COOKIE_HEADER.equalsIgnoreCase(name))
            {
                return new Enumeration()
                {
                    public boolean hasMoreElements()
                    {
                        return false;
                    }

                    public Object nextElement()
                    {
                        return null;
                    }
                };
            }
            return super.getHeaders(name);
        }

        @Override
        public Cookie[] getCookies()
        {
            Cookie[] cs = super.getCookies();
            List<Cookie> cokRet = new ArrayList<Cookie>(cs.length);
            for (Cookie c : cs)
            {
                if (c.getName().equalsIgnoreCase(JSESSIONID)) continue;
                cokRet.add(c);
            }

            return cokRet.toArray(new Cookie[] {});
        }

    }

And really think to forget all about Session and just use the session Id as just a unique identifier to the user, and do it myself the hard way.

Muhammad Hewedy
  • 29,102
  • 44
  • 127
  • 219

3 Answers3

5

As to your code, don't do it the hard way, use HttpServletRequest#getRequestedSessionId() and HttpServletRequest#isRequestedSessionIdValid() instead to check the requested session ID and if it is valid.

if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
    // The session has been expired (or a hacker supplied a fake cookie).
}

As to your concrete problem:

the code of accessing cookies makes the session keep active and don't timeout!

No, the code doesn't do that. It's the HTTP request itself which does that. It is not true that whenever you don't call getSession() or something, the session timeout won't be postponed. It will be postponed on every single HTTP request fired by the client, regardless of whether you need the session in the code.

To learn about how sessions work, you may find this answer helpful: How do servlets work? Instantiation, sessions, shared variables and multithreading

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
1

The session expiring isn't dependent on your code accessing the session, it depends on the user making a request with that session. Every time the user makes a request, the session's timeout will reset itself.

If you want to not have the user's request re-set the timeout (ie. have a fixed-length session), then you will need to do additional things for configuring the session, including possibly using a different filter to handle sessions.

cdeszaq
  • 30,869
  • 25
  • 117
  • 173
  • I've added a filter (shown above) but It seems that the Session Object is being created (based on `cookie` header) before even the request reach any filter/servlet, and this is logical. – Muhammad Hewedy Jan 24 '12 at 16:35
0

The session is not timeout, that is correct behavior, because request was accepted and session expiration is updated in any case.

e-zinc
  • 4,491
  • 2
  • 20
  • 17