2

我正在使用 Tomcat 7 并尝试将一些对象存储到会话中,但是每当有来自同一个客户端的新请求时,看起来 Tomcat 正在创建一个新会话。

以下是我的代码,它基本上是一个过滤器,它调用另一个执行身份验证和授权并返回一个对象的应用程序。我正在使用 Apache httpclient 进行此通信

过滤器类

    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>

怎样做才能使 Tomcat 为来自同一客户端的请求维护会话?

我尝试了以下对我不起作用的选项。

  1. 在全局 context.xml 中添加 Valve,例如 <Valve className="org.apache.catalina.authenticator.BasicAuthenticator" changeSessionIdOnAuthentication="false"/>

  2. <http-only>true</http-only>从 web.xml 中删除选项

据我了解,由于会话固定保护问题,Tomcat 会为每个请求创建新的会话 ID,但是还有其他替代方法来维护会话吗?

4

1 回答 1

4

<secure>true</secure>意味着cookie应该在HTTPS连接中设置,我想你是在做HTTP,所以删除它

于 2013-10-17T20:23:07.750 回答