Jsp 防止用户在注销后看到以前访问过的安全页面

Jsp 防止用户在注销后看到以前访问过的安全页面,jsp,servlets,logout,back-button,browser-history,Jsp,Servlets,Logout,Back Button,Browser History,我要求最终用户在注销/注销后不能返回受限页面。但目前,最终用户可以通过浏览器后退按钮、访问浏览器历史记录,甚至在浏览器的地址栏中重新输入URL来实现这一点 基本上,我希望最终用户在注销后不能以任何方式访问受限页面。我怎样才能做到最好?我可以用JavaScript禁用后退按钮吗?您可以也不应该禁用浏览器后退按钮或历史记录。这不利于用户体验。有JavaScript攻击,但它们不可靠,并且在客户端禁用JS时也不起作用 您的具体问题是请求的页面是从浏览器缓存加载的,而不是直接从服务器加载的。这本质上是无

我要求最终用户在注销/注销后不能返回受限页面。但目前,最终用户可以通过浏览器后退按钮、访问浏览器历史记录,甚至在浏览器的地址栏中重新输入URL来实现这一点


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

您可以也不应该禁用浏览器后退按钮或历史记录。这不利于用户体验。有JavaScript攻击,但它们不可靠,并且在客户端禁用JS时也不起作用

您的具体问题是请求的页面是从浏览器缓存加载的,而不是直接从服务器加载的。这本质上是无害的,但对最终用户来说确实是令人困惑的,因为他/她错误地认为它确实来自服务器

您只需要指示浏览器而不是缓存所有受限制的JSP页面(因此不仅仅是注销页面/操作本身!)。这样,浏览器将被迫从服务器而不是缓存请求页面,因此将执行服务器上的所有登录检查。您可以使用设置
doFilter()
方法中的:

@WebFilter
公共类NoCacheFilter实现过滤器{
@凌驾
public void doFilter(ServletRequest-req、ServletResponse-res、FilterChain-chain)抛出IOException、ServletException{
HttpServletResponse=(HttpServletResponse)res;
setHeader(“缓存控制”,“无缓存,无存储,必须重新验证”);//HTTP 1.1。
response.setHeader(“Pragma”,“无缓存”);//HTTP 1.0。
response.setDateHeader(“Expires”,0);//代理。
链式过滤器(要求、恢复);
}
// ...
}
将此
过滤器
映射到感兴趣的
url模式
,例如
*.jsp

@WebFilter("*.jsp")
或者,如果您只想将此限制放在安全页面上,那么您应该指定一个覆盖所有这些安全页面的URL模式。例如,当它们都在文件夹
/app
中时,您需要指定
/app/*
的URL模式

@WebFilter("/app/*")
更重要的是,您可以在检查登录用户是否存在的相同
过滤器中执行此操作

测试前不要忘记清除浏览器缓存!;)

另见:

您可以尝试告诉浏览器不要缓存主页(使用适当的标题-Expires、cache Control、Pragma)。但这并不能保证有效。您可以做的是在页面加载时对服务器进行ajax调用,以检查用户是否已登录,如果未登录,则执行重定向。

*。如果转发页面,Url模式中的jsp将不起作用。尝试也包括您的servlet。。这将使您的应用程序不受后退按钮问题的影响。

不禁用浏览器后退的最简单方法是将此代码添加到您不希望用户在注销后返回的页面的
页面加载事件中:

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

正确的方法是添加

Vary: Cookie

安全页面上的标题。当用户注销时,清除其会话cookie。然后,当他们注销后返回时,浏览器缓存将丢失。这还具有不完全破坏缓存的好处。

实现过滤器的另一种方法是在所有受保护的JSP或所有路径上设置“无缓存”过滤器。如果应用程序很小,并且希望仅为特定页面自定义此属性,则这可能是一个好主意。我们可以在每个不应缓存的安全JSP上添加以下Java代码段:

<%
  response.addHeader("Pragma", "no-cache");
  response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  response.setDateHeader("Expires", 0);
%>


如果不在JSP上,这也可以用于定义路由并为“HttpServletResponse”对象设置头的控制器。

有时这还不够,我记得有这样的问题。浏览器只记得最后一页。但可能是IE6,我想不起来了:)@Bozho:要么你提供了一组不完整的标题,要么浏览器的页面仍在缓存中。@Chris:适用于Firefox和所有其他浏览器。你的问题是由别的地方引起的。也许你忘了清理一些缓存?或者这些标题设置在错误的响应上?@BalusC我创建了一个单独的筛选器类来覆盖
doFilter()
方法。当我按下注销按钮时,它被重定向到一个servlet,在这里我使会话无效。我不确定
doFilter()
方法是如何在这里发挥作用的。你能告诉我怎么实施吗?如中所示,请选择要遵循的正确步骤。谢谢,对我来说很好。在
sendRedirect(…)
forward()
之后进行测试。但是,如果一个邪恶的头脑禁用了JavaScript,这不起作用,他仍然会看到页面。使用Post-request-get模式。谷歌它。虽然你的答案很有用,但请发布与OP所选编程语言相关的答案。您的C#解决方案对OP的JavaEE项目没有帮助。