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; } }
以上內容都來自於網絡搜索整理,涉及到的網址以下: