我正试图找出如何在Glassfish 3.1中防止JSF登录表单上的会话固定。使用Servlet很容易,所以我尝试使用JSF做同样的事情(基于这个问题:从JSF请求中检索会话ID值):
FacesContext fCtx = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) fCtx.getExternalContext().getSession(false);
session.invalidate();
fCtx.getExternalContext().getSession(true);
它似乎有效,但当我点击浏览器的后退按钮并重新输入登录详细信息时,我会得到:
javax.faces.application.ViewExpiredException:viewId:/index.xhtml-视图/无法还原index.xhtml。
只有在"刷新"并重新发送后,它才能再次工作。
这可能是什么原因?
您需要指示浏览器不要缓存JSF页面。创建一个映射为@WebFilter(servletNames={"facesServlet"})
的Filter
,并在doFilter()
方法中执行以下工作
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(req, res);
这将迫使浏览器在按下后退按钮时启动一个全新的GET请求。否则,它只会从缓存中返回页面,然后表单提交将失败,因为服务器端视图状态已随着会话无效而丢失。