我创建了一个ASP.Net Web窗体应用程序使用Visual Studio 2013,我正在使用.NET框架4.5.我想确保我的网站不受跨网站请求伪造(CSRF)的影响,我发现很多文章都在讨论如何在MVC应用程序上实现这一功能,但很少有文章讨论Web表单.在this StackOverflow question条 comments 中,有一条 comments 说

"这是一个老问题,但最新的Visual Studio 2012 ASP.NET

我的母版页不包含该答案中提到的代码.它真的包含在新的应用程序中吗?如果没有,添加它的最佳方式是什么?

推荐答案

ViewStateUserKey双重提交Cookie(&A)

从Visual Studio 2012开始,微软在新的web表单应用程序项目中添加了内置的CSRF保护.要使用此代码,请添加一个新的ASP.NET Web窗体应用程序添加到您的解决方案并查看网站.主代码隐藏在页面后面.此解决方案将对从网站继承的所有内容页应用CSRF保护.母版页.

要使此解决方案发挥作用,必须满足以下要求:

所有修改数据的web表单都必须使用该网站.母版页.

public partial class SiteMaster : MasterPage
{
  private const string AntiXsrfTokenKey = "__AntiXsrfToken";
  private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
  private string _antiXsrfTokenValue;

  protected void Page_Init(object sender, EventArgs e)
  {
    //First, check for the existence of the Anti-XSS cookie
    var requestCookie = Request.Cookies[AntiXsrfTokenKey];
    Guid requestCookieGuidValue;

    //If the CSRF cookie is found, parse the token from the cookie.
    //Then, set the global page variable and view state user
    //key. The global variable will be used to validate that it matches 
    //in the view state form field in the Page.PreLoad method.
    if (requestCookie != null
        && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
    {
      //Set the global token variable so the cookie value can be
      //validated against the value in the view state form field in
      //the Page.PreLoad method.
      _antiXsrfTokenValue = requestCookie.Value;

      //Set the view state user key, which will be validated by the
      //framework during each request
      Page.ViewStateUserKey = _antiXsrfTokenValue;
    }
    //If the CSRF cookie is not found, then this is a new session.
    else
    {
      //Generate a new Anti-XSRF token
      _antiXsrfTokenValue = Guid.NewGuid().ToString("N");

      //Set the view state user key, which will be validated by the
      //framework during each request
      Page.ViewStateUserKey = _antiXsrfTokenValue;

      //Create the non-persistent CSRF cookie
      var responseCookie = new HttpCookie(AntiXsrfTokenKey)
      {
        //Set the HttpOnly property to prevent the cookie from
        //being accessed by client side script
        HttpOnly = true,

        //Add the Anti-XSRF token to the cookie value
        Value = _antiXsrfTokenValue
      };

      //If we are using SSL, the cookie should be set to secure to
      //prevent it from being sent over HTTP connections
      if (FormsAuthentication.RequireSSL &&
          Request.IsSecureConnection)
      {
        responseCookie.Secure = true;
      }

      //Add the CSRF cookie to the response
      Response.Cookies.Set(responseCookie);
    }

    Page.PreLoad += master_Page_PreLoad;
  }

  protected void master_Page_PreLoad(object sender, EventArgs e)
  {
    //During the initial page load, add the Anti-XSRF token and user
    //name to the ViewState
    if (!IsPostBack)
    {
      //Set Anti-XSRF token
      ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;

      //If a user name is assigned, set the user name
      ViewState[AntiXsrfUserNameKey] =
             Context.User.Identity.Name ?? String.Empty;
    }
    //During all subsequent post backs to the page, the token value from
    //the cookie should be validated against the token in the view state
    //form field. Additionally user name should be compared to the
    //authenticated users name
    else
    {
      //Validate the Anti-XSRF token
      if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue
          || (string)ViewState[AntiXsrfUserNameKey] !=
               (Context.User.Identity.Name ?? String.Empty))
      {
        throw new InvalidOperationException("Validation of " +
                            "Anti-XSRF token failed.");
      }
    }
  }
}

Source

Asp.net相关问答推荐

如何将标头中的用户名/密码传递给 SOAP WCF 服务

web.config 部分的单独配置文件

SignalR 不在服务器上使用 Session

ASP.NET 如何将控件呈现为 HTML?

您对 Windows Workflow Foundation 有何体验?

无法确定条件表达式的类型,因为 'string' 和 'System.DBNull' 之间没有隐式转换

为应用程序池Classic .NET AppPool提供服务的进程与 Windows 进程激活服务发生了致命的通信错误

DropDownList AppendDataBoundItems(第一项为空白且无重复项)

如何在 ASP.Net 的客户端 (JavaScript) 上判断 Page.Validate()?

将当前谷歌 map 保存为图片

捕获的异常本身为 null !

投票有什么问题?

IIS - 无法通过 ip 地址而不是 localhost 访问页面

ASP.NET MVC 和 httpRuntime executionTimeout

简单的 LINQ 和列表错误:WhereListIterator`1[Task]' to type 'System.Collections.Generic.List`1[Task]'

.Net System.Mail.Message 添加多个收件人地址

为什么 Controls 集合不提供所有 IEnumerable 方法?

~/ 等价于 javascript

字体真棒里面asp按钮

ASP.NET MVC 5 Web.config:FormsAuthenticationModule或FormsAuthentication