asp.net - 仅当从已空闲一段时间的移动浏览器发回时,“视图状态 MAC 验证失败”
问题描述
我知道这个问题在 StackOverflow 上经常被问到,但我的情况有点不同。我检查了与此问题相关的所有答案,但没有一个能解决我的问题,因为在我的情况下,它只发生在移动设备上的浏览器上。
从已打开一段时间的移动浏览器发回时,我只会收到“ViewState MAC 验证失败”错误。从计算机浏览器提交表单时,该错误永远不会出现。大多数情况下,从移动浏览器提交时,它都不会出现。它仅在我打开一段时间以来已提交的移动选项卡并再次单击提交按钮时出现。
但是,当我关闭浏览器(因此它不在移动后台运行)时,它也会一直发生,再次打开它并重新提交表单。我想这是此错误背后的主要问题(重新启动浏览器会导致在移动设备上重新加载页面,然后再单击任何内容)。
我尝试了以下解决方案,但都没有奏效:
- 手动将 MachineKey 设置为我的
web.config
- 使用 aspnet_regiis 实用程序运行将保留机器密钥的托管应用程序。
- 本文提出的解决方案
LoadUserProfile = True
在应用程序池中设置- 在 IIS 应用程序池中设置
SessionTimeout = 0
。 - 通过 http 保护我的 cookie。
注意:我知道我的设置enableViewStateMac="false"
会web.config
解决我的问题,但我真的不希望这样做以避免我的应用程序中的安全性贬值。
经过几次测试,我注意到该错误仅在移动浏览器强制重新加载/重新启动页面时产生。例如,如果我重新提交已经从手机提交的表单,大多数情况下它不会产生错误。但是,有时,当我在移动设备上打开浏览器时,它会在我单击任何内容之前强制重新加载/重新启动页面。现在,当我单击提交按钮时,会出现错误。
ViewState
由于正在更改,因此此强制重新加载/重新启动可能会导致此错误。
另一种可能性是,即使我在 IIS 中将会话设置为不会过期,移动设备也会使会话过期。
然而,另一种可能性是移动设备不允许浏览器在后台运行,导致当用户再次打开浏览器时强制重新加载以重新构建页面。
我在我的应用程序中使用以下代码:
Partial Class MasterPage
Inherits System.Web.UI.MasterPage
Private Const AntiXsrfTokenKey As String = "__AntiXsrfToken"
Private Const AntiXsrfUserNameKey As String = "__AntiXsrfUserName"
Private _antiXsrfTokenValue As String
Protected Sub Page_Init(sender As Object, e As EventArgs)
' The code below helps to protect against XSRF attacks
Dim requestCookie = Request.Cookies(AntiXsrfTokenKey)
Dim requestCookieGuidValue As Guid
If requestCookie IsNot Nothing AndAlso Guid.TryParse(requestCookie.Value, requestCookieGuidValue) Then
' Use the Anti-XSRF token from the cookie
_antiXsrfTokenValue = requestCookie.Value
Page.ViewStateUserKey = _antiXsrfTokenValue
Else
' Generate a new Anti-XSRF token and save to the cookie
_antiXsrfTokenValue = Guid.NewGuid().ToString("N")
Page.ViewStateUserKey = _antiXsrfTokenValue
Dim responseCookie = New HttpCookie(AntiXsrfTokenKey) With {
.HttpOnly = True,
.Value = _antiXsrfTokenValue
}
If FormsAuthentication.RequireSSL AndAlso Request.IsSecureConnection Then
responseCookie.Secure = True
End If
Response.Cookies.[Set](responseCookie)
End If
AddHandler Page.PreLoad, AddressOf master_Page_PreLoad
End Sub
Protected Sub master_Page_PreLoad(sender As Object, e As EventArgs)
If Not IsPostBack Then
' Set Anti-XSRF token
ViewState(AntiXsrfTokenKey) = Page.ViewStateUserKey
ViewState(AntiXsrfUserNameKey) = If(Context.User.Identity.Name, [String].Empty)
Else
' Validate the Anti-XSRF token
If DirectCast(ViewState(AntiXsrfTokenKey), String) <> _antiXsrfTokenValue OrElse DirectCast(ViewState(AntiXsrfUserNameKey), String) <> (If(Context.User.Identity.Name, [String].Empty)) Then
Throw New InvalidOperationException("Validation of Anti-XSRF token failed.")
End If
End If
End Sub
Private Sub MasterPage_Load(sender As Object, e As EventArgs) Handles Me.Load
'Add Base Path and Canonical URL
Dim strBasePath = "<base href='" & AppSettings("LivePath") & "' />"
Page.Header.Controls.Add(New LiteralControl(strBasePath))
End Sub
End Class
我希望有一个解决方案,因为我不想最终设置enableViewStateMac="false"
在我的web.config
[更新]
潜在解决方案:
我目前对此的潜在解决方案是处理“ViewState MAC 验证失败”错误,并向用户提示自定义消息,解释表单验证失败。这样,安全性和可用性就得到了平衡。
我受到这篇文章的启发,因为这个可能是短暂的解决方案。
解决方案
推荐阅读
- swift - WatchKit HealthKit - 当以两种不同的方式访问时,时间跨度的步长范围是不同的
- html - 使用scss和html根据背景颜色动态更改进度条的字体颜色
- r - 单列或单行中的多列数据
- java - Spring从具有另一个签名的方法中驱逐缓存
- python - 将列表项添加到列 csv
- json - 如何在swift中根据JSON参数值删除带有按钮的CollectionView单元格
- php - Laravel 验证器需要不需要的东西
- opencv - 用于 GTX 1080Ti 的 OpenCV CUDA_ARCH_BIN
- node.js - 来自用户的隔离且不安全的代码 - 如何在 NodeJS 中运行?
- javascript - 如何使用 innerHTML 呈现正确的内容