设置Page.ViewStateUserKey后反序列化视图状态字符串

时间:2013-08-27 04:41:04

标签: asp.net viewstate object-serialization

我正在使用自动生成的代码来防止使用asp.net Web应用程序进行跨站点伪造攻击 - 即:

protected const string AntiXsrfTokenKey = "__AntiXsrfToken";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
{
    var requestCookie = Request.Cookies[AntiXsrfTokenKey];
    Guid requestCookieGuidValue;
    if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
    {
         _antiXsrfTokenValue = requestCookie.Value;
         Page.ViewStateUserKey = _antiXsrfTokenValue;

当使用Ajax / Webmethod请求时,我还希望在更改数据库之前验证请求,方法是回发_VIEWSTATE隐藏输入的值。

然而,当我尝试

internal static void Validate(string encodedViewstate)
{
     var request = HttpContext.Current.Request;
     var requestCookie = request.Cookies[AntiXsrfTokenKey];
     var antiXsrfTokenValue = requestCookie.Value;
     var los = new System.Web.UI.LosFormatter(true, antiXsrfTokenValue);
     var xsrfData = los.Deserialize(encodedViewstate);

los.Deserialize方法失败:

 Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey> configuration specifies the same validationKey and validation algorithm

即,单独的UserKey不是编码的视图状态字符串的正确密钥。

在设置ViewStateUserKey属性(即MAC和UserKey的某种组合)之后,任何人都可以帮助解决如何对视图状态进行反序列化的问题。感谢您的想法/专长。

1 个答案:

答案 0 :(得分:1)

您需要使用Page本身使用的相同PageStatePersister实例。否则此检查将无法可靠地运行。例如,在Page的代码隐藏中考虑这个实例方法:

private void CheckCsrfToken() {
    var persister = this.PageStatePersister;
    persister.Load();
    if (persister.ViewState == null) {
        throw new Exception("Validation failed.");
    }
}

只要设置了Page.ViewStateUserKey,返回的persister实例的修饰符也会相应设置。