https跳转到http session丢失问题

http>https>httphtml

session是不会丢失的。java

这个就是用户登陆时候经过http访问了首页,或者页面,而后点击登陆按钮,跳转到https协议下,输入完毕用户名密码等信息,登陆录成功,在服务端session放入当前登陆用户信息.web

这种跳转方式不会出现session丢失状况。浏览器

 

这时候,若是用户没有访问你的http页面,而是直接经过https访问你的登陆页面,这时候就是 tomcat

https>http安全

用户输入完用户名密码等信息,登陆成功,在服务端session放入当前用户信息, 再跳转回http的页面, session就丢失了, 说丢失可能不严谨(其实session还在服务端保存,只是tomcat帮咱们建立了新的session id致使咱们的会话跟踪失效)。cookie


缘由分析网络

实际上无论在https,仍是http写一下,web server都会建立session。Web server与浏览器之间能够经过cookie(JSESSIONID)或url(增长jessionid参数)这两种方法传递session信息。session

从 Tomcat4.0开始,加强了安全性,web server不会把https下建立的session以cookie形式传给http response。app

而下面的解决方法,当是新的 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

相关文章
相关标签/搜索