Странное необработанное исключение из приложения asp.net - не удалось выполнить проверку MAC-адреса viewstate

Я не знаю, видел ли кто-нибудь этот вопрос раньше, но я просто в тупике. Здесь необработанное сообщение об исключении, которое моя страница ошибки захватывает.

Сообщение об ошибке: подтверждение MAC-адрес viewstate не удался. Если это приложение размещено веб-фермой или кластера, убедитесь, что конфигурация указывает тот же валидационный ключ и алгоритм проверки. AutoGenerate не могут использоваться в кластере.

Трассировка стека: при System.Web.UI.ViewStateException.ThrowError(Exception внутренний, String persistedState, String errorPageMessage, Boolean macValidationError) в System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) в System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState) в System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState) в System.Web.UI.HiddenFieldPageStatePersister.Load() в System.Web.UI.Page.LoadPageStateFromPersistenceMedium() в System.Web.UI.Page.LoadAllState() в System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) в System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) в System.Web.UI.Page.ProcessRequest() в System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext контекста) в System.Web.UI.Page.ProcessRequest(HttpContext контекста) в ASP.generic_aspx.ProcessRequest(HttpContext контекста) в System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() в System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean & completedSynchronously)

Источник: System.Web

У кого-нибудь есть идеи о том, как я могу это решить? Спасибо.

Ответ 1

Мне кажется, что эта ошибка может возникнуть, если вы нажмете кнопку/ссылку и т.д. до того, как страница полностью загрузится.

Если это так, ошибка вызвана функцией ASP.net 2.0, называемой Event Validation. Это функция безопасности, которая гарантирует, что действия обратной передачи происходят только из событий, разрешенных и созданных сервером, чтобы предотвратить ложную обратную передачу. Эта функция реализуется путем управления событиями, которые регистрируют действительные события при их рендеринге (как и во время их реальных методов Render()). Конечным результатом является то, что в нижней части form tag, вы увидите что-то вроде этого:

<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"  value="AEBnx7v.........tS" />

Когда происходит обратная передача, ASP.net использует значения, хранящиеся в этом скрытом поле, чтобы убедиться, что нажатая кнопка вызывает действительное событие. Если он недействителен, вы получаете исключение, которое вы видели.

Проблема, которую вы видите, происходит специально, когда вы выполняете обратную передачу до того, как поле EventValidation было отображено. Если EventValidation включен (по умолчанию это он), но ASP.net не видит скрытого поля при обратной передаче, вы также получаете исключение. Если вы отправляете форму до того, как она будет полностью отображена, то вероятность того, что поле EventValidation еще не было отображено, и, следовательно, ASP.net не может подтвердить ваш клик.

Одна работа вокруг - это, конечно, просто отключить проверку событий, но вы должны знать о последствиях безопасности. В качестве альтернативы, просто никогда не отправляйте назад до того, как форма закончит рендеринг. Конечно, это сложно сказать вашим пользователям, но, возможно, вы можете отключить пользовательский интерфейс до тех пор, пока форма не будет отображаться?

из http://forums.asp.net/p/955145/1173230.aspx

Ответ 3

У вас есть несколько серверов, на которых запущено это приложение, и/или есть веб-сад? Если да, вам нужно будет установить машинный ключ в файле web.config

Ответ 4

По умолчанию ASP.NET включает в себя цифровую подпись значения ViewState на странице. Это делается автоматически сгенерированным ключом, который хранится в памяти. Это делается для того, чтобы злоумышленник не мог изменять ViewState из браузера и, например, предоставлять ему доступ к материалам, к которым у них обычно не было доступа.

ASP.NET также может факультативно шифровать ViewState, но по умолчанию он отключен по соображениям производительности. На многих веб-сайтах гораздо важнее удостовериться, что содержимое ViewState не "запущено", а не конфиденциально.

В сообщении об ошибке указано, что проверка подписи не удалась. Страница была опубликована с помощью ViewState, но подпись ViewState не соответствовала сигнатуре, вычисленной с помощью ключей, хранящихся на сервере.

Наиболее распространенная причина этой ошибки заключается в том, что вы используете два или более веб-серверов в подобной ферме среде: один сервер отправляет исходную страницу, подписанную с ключом в памяти на этом сервере, но страница отправляется обратно на второй (или третий...) сервер. Поскольку два или более серверов не имеют ключа подписи, подписи не совпадают.

... Если это приложение размещено веб-фермой или кластером, убедитесь, что в конфигурации указан один и тот же validationKey и алгоритм проверки. AutoGenerate не может использоваться в кластере.

В сообщении об ошибке вам следует использовать атрибут validationKey (см. подробности в MSDN) в ваш файл web.config должен жестко закодировать ключ подписи на значение, разделяемое всеми вашими серверами, вместо использования динамически сгенерированного. Таким образом, проверка подписи может выполняться независимо от того, какой сервер получает обратную передачу.

Вы можете отключить проверку, но это очень опасно. Это означает, что любой хакер с небольшим количеством свободного времени может подделывать ценности в вашем приложении. Например, если вы сохраняете цену элемента в значении ViewState, хакер может изменить значение из браузера на $0.01 прямо перед тем, как поставить заказ.

Ответ 6

Я знаю, что вы можете отключить проверку MAC-адреса viewstate, но я думаю, что если страница не загружена, вы можете столкнуться с большими проблемами. Когда я столкнулся с этой проблемой, мне пришлось отключить все кнопки, пока страница не была полностью загружена.