一.場景:
在企業內網應用,以及一些安全要求不高的網站會有一些https轉http的需求,例如隻是登陸https協議,其他請求都是走http協議,走http協議不再需要重新登陸一次。
二.解決方案
Cookie時效:
當cookie是secure的情況下,當服務器從https協議重定向到http協議後,這樣的cookie就不會隨請求發送到服務器。
當cookie不是secure的情況下,當服務器從http協議重定向到https協議後,這樣的cookie就不會隨請求發送到服務器。
所以解決的方法就是在https認證後,除瞭構造一個secure的cookie(包含session id信息),同時構造一個非secure的cookie(包含session id信息),這樣頁面跳轉後就一致保持session有效瞭,從而達到https重定向到http後不需要登陸的效果。
圖中沒有詳細描述web容器的跳轉,僅僅想描述協議轉換的實現過程。
主要點說明:
重定向跳轉在頁面中實現,而不在Authenticator實現,也不在Filter實現,因為Response已經commit。
Filter實現增加非Secure cookie的邏輯,代碼:
[java]
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class HttpsCookieFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest httpRequest = (HttpServletRequest) request;
final HttpServletResponse httpResponse = (HttpServletResponse) response;
final HttpSession session = httpRequest.getSession(false);
// servlet3
if (session != null) {
System.out.println("HttpsCookieFilter set session cookie:"
+ session.getId());
final Cookie cookie = new Cookie("JSESSIONID",
session.getId());
cookie.setMaxAge(-1);//no store
cookie.setSecure(false);
cookie.setPath(httpRequest.getContextPath());
cookie.setHttpOnly(true);
httpResponse.addCookie(cookie);
}
//servlet2
//httpResponse.addHeader(
// "Set-Cookie",
// "JSESSIONID=" + session.getId() + "; Path="
// + httpRequest.getContextPath() + "; HttpOnly");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}