http>https>http
session是不会丢失的。
这个就是用户登录时候通过http访问了首页,或者页面,然后点击登录按钮,跳转到https协议下,输入完毕用户名密码等信息,登录录成功,在服务端session放入当前登录用户信息.
这种跳转方式不会出现session丢失情况。
这时候,如果用户没有访问你的http页面,而是直接通过https访问你的登录页面,这时候就是
https>http
用户输入完用户名密码等信息,登录成功,在服务端session放入当前用户信息, 再跳转回http的页面, session就丢失了, 说丢失可能不严谨(其实session还在服务端保存,只是tomcat帮我们创建了新的session id导致我们的会话跟踪失效)。
原因分析
实际上不管在https,还是http写一下,web server都会创建session。Web server与浏览器之间可以通过cookie(JSESSIONID)或url(增加jessionid参数)这两种方法传递session信息。
从 Tomcat4.0开始,增强了安全性,web server不会把https下创建的session以cookie形式传给http response。
而下面的解决方法,当是新的 https session 时,创建一个JSESSIONID的cookie,并设置到 http resonse 中,这样当从https转到http时,http response中有了JSESSIONID,因此就没有问题了。
这就是登录问题产生的根本原因。
解决方法:
其主要思路是建立一个filter, 对所有的Servlet Request做处理,如果session是新的 https session,则创建一个JSESSIONID cookie,并设置到Servlet Response中,这样就突破了tomcat的限制,把https下的session传递到http协议下。
HttpsHttpTrickFilter :
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* One way to maintain the session in Tomcat, when the session cookie is getting
* created in SSL mode is to trick the browser by creating the non-secure cookie,
* when the secure cookie is getting created. To do that, we need to create an
* request wrapper
*/
public class HttpsHttpTrickFilter implements javax.servlet.Filter {
public void destroy() {
// do nothing
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// create the requestWrapper in order to process the cookie
SecureRequestWrapper requestWrapper = new SecureRequestWrapper((HttpServletRequest)request);
requestWrapper.setResponse((HttpServletResponse)response);
// continue
chain.doFilter(requestWrapper, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
// do nothing
}
}
SecureRequestWrapper:
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* One way to maintain the session in Tomcat, when the session cookie is getting
* created in SSL mode is to trick the browser by creating the non-secure cookie,
* when the secure cookie is getting created. To do that, we need to create an
* request wrapper
*/
public class SecureRequestWrapper extends HttpServletRequestWrapper {
private HttpServletResponse response = null;
public SecureRequestWrapper(HttpServletRequest request) {
super(request);
}
public void setResponse(HttpServletResponse response) {
this.response = response;
}
public HttpSession getSession() {
HttpSession session = super.getSession();
processSessionCookie(session);
return session;
}
public HttpSession getSession(boolean create) {
HttpSession session = super.getSession(create);
processSessionCookie(session);
return session;
}
private void processSessionCookie(HttpSession session) {
if (null == response || null == session) {
return;
}
// cookieOverWritten - Flag to filter multiple "Set-Cookie" headers
Object cookieOverWritten = getAttribute("COOKIE_OVERWRITTEN_FLAG");
if (null == cookieOverWritten && isSecure() && isRequestedSessionIdFromCookie() && session.isNew()) {
Cookie cookie = createCookie(session);
// Adding an "Set-Cookie" header to the response
response.addCookie(cookie);
// To avoid multiple "Set-Cookie" header
setAttribute("COOKIE_OVERWRITTEN_FLAG", "true");
}
}
/**
* Might have created the cookie in SSL protocol and tomcat will loose the session
* if there is change in protocol from HTTPS to HTTP. To avoid
* this, trick the browser using the HTTP and HTTPS session cookie.
* @param session
*
* @return the cookie
*/
private Cookie createCookie(HttpSession session) {
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(-1); // Life of the browser or timeout
String contextPath = getContextPath();
if ((contextPath != null) && (contextPath.length() > 0)) {
cookie.setPath(contextPath);
}
else {
cookie.setPath("/");
}
return cookie;
}
}
以上内容都来自于网络搜索整理,涉及到的网址如下:
http://javaarm.com/faces/display.xhtml?tid=2853
http://name327.iteye.com/blog/1591796


所有评论(0)