我正在使用 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 为来自同一客户端的请求维护会话?
我尝试了以下对我不起作用的选项。
在全局 context.xml 中添加 Valve,例如
<Valve className="org.apache.catalina.authenticator.BasicAuthenticator" changeSessionIdOnAuthentication="false"/>
<http-only>true</http-only>
从 web.xml 中删除选项
据我了解,由于会话固定保护问题,Tomcat 会为每个请求创建新的会话 ID,但是还有其他替代方法来维护会话吗?