C# 在ASP MVC 3中使页面会话过期的可能方法?(“注销后按后退按钮”;

C# 在ASP MVC 3中使页面会话过期的可能方法?(“注销后按后退按钮”;,c#,asp.net-mvc-3,razor,C#,Asp.net Mvc 3,Razor,我目前正在MVC3网站上进行用户身份验证 我有一个安全问题,我想防止用户在成功退出页面后按“后退”按钮重新登录 我曾研究过许多解决方案,但我不知道如何将其应用到我的项目中。是否有可能在MVC3中实现这一点?当用户单击“后退”按钮时,浏览器只是重新显示缓存的页面 如果希望浏览器不缓存页面并防止这种情况发生,则必须使用HTTP响应头来指示它 您需要在不希望缓存的每个HTTP响应中运行以下代码: HttpContext.Current.Response.AddHeader("Cache-Control

我目前正在MVC3网站上进行用户身份验证

我有一个安全问题,我想防止用户在成功退出页面后按“后退”按钮重新登录


我曾研究过许多解决方案,但我不知道如何将其应用到我的项目中。是否有可能在MVC3中实现这一点?

当用户单击“后退”按钮时,浏览器只是重新显示缓存的页面

如果希望浏览器不缓存页面并防止这种情况发生,则必须使用HTTP响应头来指示它

您需要在不希望缓存的每个HTTP响应中运行以下代码:

HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Cache-Control", "private"); //to be safe cross browser
如果在自定义基本控制器(如下)中包含此代码,则可以避免整个站点的代码重复:

public class CustomBaseController : Controller
{
    protected override void OnResultExecuting(ResultExecutingContext context)
    {   
        HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
        HttpContext.Current.Response.AddHeader("Cache-Control", "private"); //to be safe cross browser
    }
}

如果您使用上述方法,请确保您的所有控制器都继承自“CustomBaseController”,如果您不希望它们允许用户使用后退按钮查看缓存页面

当用户单击后退按钮时,浏览器只是重新显示缓存页面

如果希望浏览器不缓存页面并防止这种情况发生,则必须使用HTTP响应头来指示它

您需要在不希望缓存的每个HTTP响应中运行以下代码:

HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Cache-Control", "private"); //to be safe cross browser
如果在自定义基本控制器(如下)中包含此代码,则可以避免整个站点的代码重复:

public class CustomBaseController : Controller
{
    protected override void OnResultExecuting(ResultExecutingContext context)
    {   
        HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
        HttpContext.Current.Response.AddHeader("Cache-Control", "private"); //to be safe cross browser
    }
}

如果使用上述方法,请确保所有控制器都继承自“CustomBaseController”当您不希望他们允许用户使用“后退”按钮查看缓存页面时,John解决方案的问题在于缓存实际上非常有用,您可能不想从应用程序中删除此功能


解决此问题的一个简单方法是,如果用户注销,则强制输出html页面刷新自身。这可以通过在请求开始时使用JavaScript将ajax请求发送回服务器,并验证用户是否仍在登录来实现。如果用户已注销,只需执行客户端重定向到相同的页面。这将有效地解决您的问题。

John解决方案的问题是缓存实际上非常有用,您可能不想从应用程序中删除此功能


解决此问题的一个简单方法是,如果用户注销,则强制输出html页面刷新自身。这可以通过在请求开始时使用JavaScript将ajax请求发送回服务器,并验证用户是否仍在登录来实现。如果用户已注销,只需执行客户端重定向到相同的页面。这将有效地解决您的问题。

您没有重新登录,您只是从浏览器缓存中查看页面。如果您尝试调试,您将看到浏览器上的“后退”按钮上没有执行任何代码。如果您在注销并按“后退”后尝试单击某个内容,您将被重定向到登录页面(如果您保留了默认的mvc3应用程序行为)

有几种解决方案,这是我的观点:

  • 您可以自定义ActionFilterAttribute,以防止在控制器上缓存或/和类似的操作,然后只需将其应用于操作/控制器:

    public class NoClientCache : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
            filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
            filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
            filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.ServerAndNoCache);
            filterContext.HttpContext.Response.Cache.SetNoStore();
    
            base.OnResultExecuting(filterContext);
        }
    }
    
  • 您可以通过触发浏览器客户端在执行注销后强制刷新

    历史。围棋(1)

  • 添加:
    如果您是从单个位置注销,则应使用第一种方法,但如果您的注销按钮位于布局页面上,则禁用所有页面上的缓存将是不好的,因此第二种方法似乎是可行的。

    您没有重新登录,您仅从浏览器缓存查看页面。如果您尝试调试,您将看到没有在上执行任何代码浏览器上的“后退”按钮。如果您在注销并按“后退”后尝试单击某个内容,您将被重定向到登录页面(如果您保留默认mvc3应用程序行为)

    有几种解决方案,这是我的观点:

  • 您可以自定义ActionFilterAttribute,以防止在控制器上缓存或/和类似的操作,然后只需将其应用于操作/控制器:

    public class NoClientCache : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
            filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
            filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
            filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.ServerAndNoCache);
            filterContext.HttpContext.Response.Cache.SetNoStore();
    
            base.OnResultExecuting(filterContext);
        }
    }
    
  • 您可以通过触发浏览器客户端在执行注销后强制刷新

    历史。围棋(1)

  • 添加:
    如果您是从单一位置注销,您应该使用第一种方法,但如果您的注销按钮位于布局页面上,则禁用所有页面上的缓存将是不好的,因此第二种方法似乎是可行的。

    用户仍然可以通过长时间单击“上一步”按钮并选择上一页返回站点。如果y不是一个问题,因为此解决方案工作正常,否则您将希望禁用缓存控制,以防止未经授权的用户查看需要的缓存页面authorization@JohnCulviner,这太傻了。我建议的方法绝对不是安全问题。你可以同样轻松地验证和更新用户的authentication state site wide。这在不删除应用程序中非常有用的组件的情况下解决了问题。为什么要禁用缓存?@smartcaveman如果您不希望计算机上的下一个用户能够通过按“后退”按钮查看上一个会话中的敏感信息,您的方法是否正确?我开发的大多数应用程序禁用缓存实际上是有利的,因为95%的内容是动态的,您通常总是想要最新的内容。这当然取决于您的应用程序。我认为,在高度安全的应用程序中,显式启用缓存的基于属性的方法可能是最好的选择。@JohnCulvin呃,在服务器和客户机之间有一个恒定的交互流可以让服务器控制客户机看到的内容