http與https切換

來源:互聯網
上載者:User
Https跳到http時session資訊丟失的分析及解決方案

部落格分類:

     

  • YMU開發
Tomcat瀏覽器WebServlet 

我們在YMU(website monitoring)項目開發過程中發現一個關於登入功能的奇怪的問題。

當按一般流程使用登入功能時是沒問題的,即:點擊官網 (http://YouMonitor.Us)的login連結,然後跳轉到https://YouMonitor.Us/login.shtml,輸入正確的使用者名稱和密碼後,則能正確轉入功能頁面(http協議)。

而如果跳過第一步,直接在瀏覽器中輸https://YouMonitor.Us/login.shtml,則不能正確轉入功能頁面。

 

原因分析

經調試發現是由於session造成的。當使用者名稱和密碼通過驗證後,YMU會在session中儲存登入使用者名稱。

 

在第二種方式下,使用者名稱被儲存在https下建立的session中,而不能被傳遞到http協議,這樣當以http協議跳轉到功能頁面時,發現session中沒有使用者名稱,系統就會認為沒有登入,就出問題了。

再深入分析session的傳遞機制,其中一種方式是通過JSESSIONID這個cookie在瀏覽器和web server之間進行傳遞的。而為了增強安全性,從tomcat 4.0開始,在https協議下產生的cookie不會被傳遞到http協議。
這就是登入問題產生的根本原因。

 

解決方案

前一段時間在網上找到一種解決方案,該方法修改tomcat的原始碼,以解除cookie傳遞的限制。該方法的缺點是每次tomcat升級都要重新修改並編譯,很不方便。

還有沒有更方便的方法呢?上周公司一同事在網上又找到一個更加簡潔和方面的方法。其主要思路是建立一個filter, 對所有的Servlet Request做處理,如果session是新的https session,則建立一個JSESSIONID cookie,並設定到Servlet Response中,這樣就突破了tomcat的限制,把https下的session傳遞到http協議下。

根據文章說明試了一下,果然成功了!這下解決了系統的一個BUG,不錯啊!

附:原始碼

 

1. 先建立Wrapper類,用於處理所有的Serverlet Request:

public class MyRequestWrapper extends HttpServletRequestWrapper{
private HttpServletResponse response = null;

public MyRequestWrapper(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) {
// No response or session object attached, skip the pre processing
return;
}

// cookieOverWritten - 用於過濾多個Set-Cookie頭的標誌
Object cookieOverWritten = getAttribute("COOKIE_OVERWRITTEN_FLAG");
if (null == cookieOverWritten && isSecure() && isRequestedSessionIdFromCookie() && session.isNew()) {
// 當是https協議,且新session時,建立JSESSIONID cookie以欺騙瀏覽器

Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(-1); // 有效時間為瀏覽器開啟或逾時
String contextPath = getContextPath();
if ((contextPath != null) && (contextPath.length() > 0)) {
cookie.setPath(contextPath);
}
else {
cookie.setPath("/");
}

response.addCookie(cookie); // 增加一個Set-Cookie頭到response
setAttribute("COOKIE_OVERWRITTEN_FLAG", "true");// 過濾多個Set-Cookie頭的標誌
}
}

}

2. 再把上述Wrapper類與Filter建立關聯:

public final class TestFilter implements Filter{
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
throws IOException, ServletException {
MyRequestWrapper myrequest = new MyRequestWrapper(request);
myrequest.setResponse(response);
chain.doFilter(myrequest, response);
}
}

 http://java-guru.iteye.com/blog/157897

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.