防止用户在注销后看到先前访问的受保护页面

我有要求,最终用户不应该能够退出/注销后返回到受限制的页面。 但目前最终用户可以通过浏览器后退button,浏览浏览器历史logging,甚至通过在浏览器的地址栏中重新inputurl来完成此操作。

基本上,我希望最终用户在退出后不能以任何方式访问受限制的页面。 我怎样才能做到最好? 我可以使用JavaScript禁用后退button吗?

可以也不应该禁用浏览器后退button或历史logging。 这对用户体验不利。 有JavaScript黑客,但它们不可靠,并且当客户端禁用JS时也不会工作。

您的具体问题是请求的页面已从浏览器caching中加载,而不是直接从服务器加载。 这基本上是无害的,但是对最终用户来说确实很混乱,因为他/她错误地认为它确实来自服务器。

您只需指示浏览器不要caching所有受限的JSP页面(因此不仅仅是注销页面/操作本身!)。 这样,浏览器被强制从服务器而不是caching中请求页面,因此服务器上的所有login检查都将被执行。 您可以使用Filter来设置doFilter()方法中必要的响应标头 。

 @WebFilter public class NoCacheFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 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); } // ... } 

将此Filter映射到感兴趣的url-pattern ,例如*.jsp

 @WebFilter("*.jsp") 

或者,如果您只想将此限制放在受保护的页面上,则应该指定一个覆盖所有受保护页面的URL模式。 例如,当它们全部位于文件夹/app ,则需要指定/app/*的URL模式。

 @WebFilter("/app/*") 

更重要的是,您可以在同一个Filter执行此项工作,因为您正在检查login用户的存在位置。

testing之前不要忘记清除浏览器caching! ;)

也可以看看:

  • 身份validationfilter和servletlogin
  • 如何在所有浏览器上控制网页caching?

如果您转发页面,Url模式中的* .jsp将不起作用。 尝试包括你的servlet ..这将使你的应用程序从这个后退button问题的安全。

在不禁用浏览器的情况下,最简单的方法是将此代码添加到页面的page_load事件中,该页面不希望用户在注销后返回:

 if (!IsPostBack) { if (Session["userId"] == null) { Response.Redirect("Login.aspx"); } else { Response.ClearHeaders(); Response.AddHeader("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate"); Response.AddHeader("Pragma", "no-cache"); } } 

您可以尝试告诉浏览器不要caching主页(使用适当的头文件 – Expires,Cache-Control,Pragma)。 但是不能保证工作。 你可以做的是,在页面加载时,对服务器进行ajax调用,以检查用户是否已login,如果没有,则redirect。

正确的方法是添加

 Vary: Cookie 

在安全页面上的标题。 当用户注销时,清除他们的会话cookie。 然后,当他们退出后回到浏览器时,浏览器caching将会丢失。 这也有没有完全击败caching的好处。