Question

I am using Tomcat 7 and trying to store some object into session, but whenever there is a new request from the same client it looks like Tomcat is creating a new session.

Following is my code which is basically a filter which is calling another application which does the Authentication and Authorization and returns an object. I am using Apache httpclient for this communication

Filter Class

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  throws IOException, ServletException {

    // If the request is for any static contents do not invoke this filter
    if (!isWorthyRequest((HttpServletRequest)request)) {
        chain.doFilter(request, response);
        return;
    }

    HttpClient httpClient = null;
    try {
        if (validateApp && request instanceof HttpServletRequest) {
            HttpServletRequest httpServletRequest = (HttpServletRequest)request;
            HttpSession httpSession = httpServletRequest.getSession(false);
            if (null != httpSession && null != httpSession.getAttribute("userInfoMap")) {
                LOG.info(" User is already Authenticated :: session Id :: "+httpSession.getId()
                        +" Created At :: "+ new Date(httpSession.getCreationTime())
                +" Last Accessed At :: "+new Date(httpSession.getLastAccessedTime()));
                // The user is already Authenticated & Authorize just pass the request to next chain
            } else {
                LOG.info("Calling Authenication / Authorization Module :: URL "+securityServiceURL);
                // Calling Authentication and Authorization
                httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(securityServiceURL);
                // Getting the SM Header
                httpPost.setHeader(IaasConstants.SM_USER, httpServletRequest.getHeader(IaasConstants.SM_USER));
                List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
                // urlParameters.add(new BasicNameValuePair(IaasConstants.SOURCE_APP_NAME, "vElite"));
                urlParameters.add(new BasicNameValuePair(IaasConstants.SUB_SERVICE_NAME, IaasConstants.SERVICE_AUTHENTICATE_USER));
                httpPost.setEntity(new UrlEncodedFormEntity(urlParameters));
                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                String jsonString = null; 
                if (null != httpEntity) {
                    jsonString = EntityUtils.toString(httpEntity);
                }
                HttpServletResponse httpServletResponse = (HttpServletResponse)response;
                // User is a valid user
                if (httpResponse.getStatusLine().getStatusCode() == HttpServletResponse.SC_OK) {
                    LOG.info(" User is valid :: user :: "+httpServletRequest.getHeader(IaasConstants.SM_USER)+" jsonObject :: "+jsonString);
                    if (null != jsonString) {
                        Gson gSon = new Gson();
                        Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
                        Map<String, Object> userInfoMap = gSon.fromJson(jsonString, mapType);
                        httpSession = httpServletRequest.getSession(false);
                        if (null == httpSession) {
                            LOG.info("Session Created and the userInfoMap is stored inside session :: ");
                            httpSession = httpServletRequest.getSession(true);
                            httpSession.setAttribute(IaasConstants.USER_INFO_MAP, userInfoMap);
                        } else {
                            httpSession.setAttribute(IaasConstants.USER_INFO_MAP, userInfoMap);
                        }
                    }
                } else {
                    // Bad User
                    LOG.info("Invalid User ::: with status code :: "
                    +httpResponse.getStatusLine().getStatusCode()
                    +" Status Message :: "+httpResponse.getStatusLine().getReasonPhrase());

                    httpServletResponse.setStatus(httpResponse.getStatusLine().getStatusCode());
                    httpServletResponse.sendError(httpResponse.getStatusLine().getStatusCode());
                    httpServletResponse.flushBuffer();
                    return;
                }
            }

        }
        HttpServletResponseCopier responseCopier = new HttpServletResponseCopier((HttpServletResponse) response);
        // pass the request along the filter chain
        chain.doFilter(request, responseCopier);

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (null != httpClient) {
            httpClient.getConnectionManager().shutdown();
        }
    }
}

/**
 * @see Filter#init(FilterConfig)
 */
public void init(FilterConfig fConfig) throws ServletException {
    // TODO Auto-generated method stub
    this.fConfig = fConfig;
    validateApp = Boolean.valueOf(fConfig.getInitParameter(IaasConstants.VALIDATE_APP));
    securityServiceURL = fConfig.getInitParameter(IaasConstants.SECURITY_SERVICE_URL);
}

   private boolean isWorthyRequest(HttpServletRequest request) {
       String url = request.getRequestURI().toString();
       Matcher m = excludeUrls.matcher(url);

       return (!m.matches());
   }

Web.xml

<session-config>
<session-timeout>15</session-timeout>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>

What to do so that Tomcat will maintain session for requests coming from same client?

I have tried following options which did not work for me.

  1. Adding Valve in global context.xml like <Valve className="org.apache.catalina.authenticator.BasicAuthenticator" changeSessionIdOnAuthentication="false"/>

  2. removing <http-only>true</http-only> option from web.xml

As I understand due to Session Fixation Protection Issue Tomcat creates new session ID for every request but then is there any other alternative to maintain session?

Was it helpful?

Solution

<secure>true</secure> means that cookie should be set only in HTTPS connection, I suppose you making HTTP, so remove it

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top