使用WebForm中的MVC2 AntiforgeryToken

时间:2012-05-31 18:47:29

标签: asp.net ajax asp.net-mvc-2 antiforgerytoken

背景

我需要从WebForms页面(托管在cms中)使用AntiForgeryToken。该页面应将数据发布到作为解决方案一部分的MVC 2.0操作。该操作应使用ValidateAntiForgeryToken属性。

我确实从这里尝试了解决方案:Using an MVC HtmlHelper from a WebForm但它似乎不起作用,因为渲染的防伪语言在控制器操作中被指示为无效。

当前解决方案

现在我已经解决了这个问题,以至于我有一个动作可以渲染一个只包含一个带有antiforgerytoken的输入标签的局部视图。

查看

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%= Html.AntiForgeryToken() %>

该页面使用javascript将antiforgerytoken拉入如下形式:

表格

<form id="jsonForm" action="/my/action" method="post">
  <input id="tokenPlaceholder" type="hidden" />

获取防伪令牌

<script type="text/javascript">
    $(function () {
        $.ajax({
            url: "/antiforgery/token",
            type: "GET",
            success: function (data, textStatus, jqXHR) {
                $("#tokenPlaceholder").replaceWith(data);
            }
        });
    });
</script>

根据ValidateAntiforgeryToken属性,表单发布有效。

问题

以这种方式向表单添加防伪令牌是否存在任何安全问题?

有没有更简单的方法我不干?

1 个答案:

答案 0 :(得分:0)

 <script>
@functions{
    public string TokenHeaderValue()
    {
        string cookieToken, formToken;
        AntiForgery.GetTokens(null, out cookieToken, out formToken);
        return cookieToken + ":" + formToken;                
    }
}

$.ajax("/antiforgery/token", {
    type: "post",
    contentType: "application/json",
    data: {  }, // JSON data goes here
    dataType: "json",
    headers: {
        'RequestVerificationToken': '@TokenHeaderValue()'
    }
});
 </script>

处理请求时,请从请求标头中提取标记。然后调用AntiForgery.Validate方法来验证令牌。如果令牌无效,则Validate方法会抛出异常。

 void ValidateRequestHeader(HttpRequestMessage request)
 {
   string cookieToken = "";
   string formToken = "";

IEnumerable<string> tokenHeaders;
if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
{
    string[] tokens = tokenHeaders.First().Split(':');
    if (tokens.Length == 2)
    {
        cookieToken = tokens[0].Trim();
        formToken = tokens[1].Trim();
    }
}
AntiForgery.Validate(cookieToken, formToken);
}

Learn more on original post