1

我继承了一个 ASP.NET 站点 (4.5)。该站点使用自动生成的 ViewState 加密密钥在单个服务器上(在托管环境中)运行。

每当站点重新启动时,尽管用户被正确地重定向到登录页面(这基本上是一个带有一些文本的 asp:Login 控件),但他们将收到 MAC 验证错误,直到他们关闭浏览器。

我想知道是否有可能/如何确保在用户登录时完全剔除/清除 ViewState 以防止发生此问题。我是否需要进行蛮力重定向或类似的操作?

我注意到登录控件的 DestinationPageUrl 设置为静态值,而不是查询字符串中的页面,这会是一个问题吗?

建议禁用 ViewState 验证、生成静态键或实现持久 ViewState 处理的答案将被否决。谢谢。

4

1 回答 1

2

我相信下面链接的 SO 帖子很好地涵盖了这一点,可能还有其他一些帖子和博客(谷歌搜索“viewstate mac 验证失败”揭示了许多解释和修复。)

在页面上停留 20 分钟以上时,视图状态 MAC 的验证失败

在某些情况下PostBackUrl,将登录名设置Button为等于您将要发回的页面名称将解决问题。

我有一个没有的案例,我正在销售 COTS 产品,不能总是依靠用户更新他们的配置来避免这个臭名昭著的问题。为了克服这个问题,我使用了一点 javascript。解决方案是这样的:

  1. 创建一个“启动画面”页面,该页面也可以用作屏幕保护程序,也许它可以显示一个徽标并每隔几秒钟在页面上随机移动它以获得良好的效果(我这样做了)。单击或点击初始屏幕页面上的某个键应将用户导航到登录表单页面 URL。
  2. 在登录表单中,将 (integer in minutes) 的值呈现Session.Timeout到 javascript 中。
  3. 编写一个 javascript 函数,该函数触发window.load并使用setInterval()或类似方法来监视未经身份验证的用户在您的登录表单上停留了多长时间。当会话超时即将到期时,重定向到 #1 中创建的启动屏幕页面。

(而不是启动屏幕方法,您可以强制刷新登录表单 - 但如果用户在周末将浏览器留在您的登录表单上,这将阻止您的 ASP.NET 应用程序由于不活动而自动关闭(假设您有一个网站的流量足够低,实际上由于不活动而关闭))。

示例代码:(把它放在你的 login.aspx 中)

<script type="text/javascript">
    var sessionTimeout = <%=Session.Timeout.ToString()%>;
    var sessionTimeoutMs = sessionTimeout * 1000;
    var refreshLoginForm = false;
    var redirectToSplashPage = true;
    setTimeout(function()
    {
        if(window.console && window.console.log) { window.console.log("ASP.NET Session expired."); }
        if(refreshLoginForm)
        {
            // method 1: refresh login form to get a fresh viewstate
            window.location.href = window.location.href;
        }
        else if (redirectToSplashPage)
        {
            // method 2: redirect to a splash screen / screen saver page
            // that will link back to login form and request a fresh viewstate.
            window.location.href = "login_splashscreen.html";
        }
    }, sessionTimeoutMs);
</script>
于 2013-10-25T20:39:37.953 回答