我有这个jquery函数,我想将防伪令牌传递给要验证的控制器。但是,无论我是通过标头还是通过正文,我当前的方法都将返回错误400。
我将此空白表格放在页面顶部
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "form" }))
{
@Html.AntiForgeryToken()
}
这是jquery函数。我在标头和正文中都有requestverificationtoken,但是它不起作用。
$("#eventGenerateButton").on("click", function (e) {
e.preventDefault();
var event_form_data = {
"__RequestVerificationToken": token,
"StartDate": $("#eventStartDate").val(),
"EndDate": $("#eventEndDate").val(),
};
$.ajax({
url: "@Url.Action("GenerateEventLogsReport", @ViewContext.RouteData.Values["controller"].ToString())",
method: "POST",
headers: { "__RequestVerificationToken": token},
xhrFields: {
responseType: 'blob'
},
data: JSON.stringify(event_form_data),
contentType: "application/json",
success: function (result) {
GenerateReport(result,"EventLogs");
},
error: function (error) {
console.log(error);
}
});
return false;
});
这是控制器
[HttpPost]
[ValidateAntiForgeryToken]
public FileResult GenerateEventLogsReport([FromBody]GenericReportDateViewModel Input)
{
}
答案 0 :(得分:0)
尝试将您的控制器签名更改为此:
public FileResult GenerateEventLogsReport(string __RequestVerificationToken, string StartDate, string EndDate)
{
}
答案 1 :(得分:0)
从event_form_data
删除令牌,然后尝试发送请求标头,如
var event_form_data = {
"StartDate": $("#eventStartDate").val(),
"EndDate": $("#eventEndDate").val(),
};
var token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
url: "/Home/AjaxPost",
method: "POST",
headers: { "RequestVerificationToken": token},
xhrFields: {
responseType: 'blob'
},
data: JSON.stringify(event_form_data),
contentType: "application/json",
success: function (result) {
},
error: function (error) {
console.log(error);
}
});
答案 2 :(得分:0)
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,
AllowMultiple = false, Inherited = true)]
///this attribute is for validating antiforgery, no matter how it's sent.
///It doesn't care if the token is in the header or body, and the body can be stringified.
public sealed class MyValidateAntiForgeryAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
var httpContext = filterContext.HttpContext;
/* Note: Antiforgery tokens are passed twice from a page. Once from
* the post itself, and once as a cookie to verify against it. The
* values do not match. They are two halves of a whole and both get
* passed into the validation routine. */
var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
//try header first
var token = httpContext.Request.Headers["__RequestVerificationToken"];
//try normal method
if (token == null)
{
for (int cl = 0; cl < httpContext.Request.Form.Keys.Count; cl++)
{
if (httpContext.Request.Form.Keys[cl] == "__RequestVerificationToken")
{
token = httpContext.Request.Form[httpContext.Request.Form.Keys[cl]];
}
}
}
//try url
if (token == null)
{
for (int cl = 0; cl < httpContext.Request.QueryString.Keys.Count; cl++)
{
if (httpContext.Request.QueryString.Keys[cl] == "__RequestVerificationToken")
{
token = httpContext.Request.QueryString[httpContext.Request.QueryString.Keys[cl]];
}
}
}
/* if still null, check to see if it's in a json string.
this section will retrieve the token out of a serialized dataset.
*/
if (token == null)
{
string json;
var position = httpContext.Request.InputStream.Position;
using (var reader = new StreamReader(httpContext.Request.InputStream, Encoding.UTF8, false, 8192, true))
{
json = reader.ReadToEnd();
//you MUST reset the input stream to start or you will break post.
httpContext.Request.InputStream.Seek(position, SeekOrigin.Begin);
try
{
var jsonObj = Json.Decode(json); //attempt to parse into json object.
token = jsonObj["__RequestVerificationToken"];
}
catch
{
//eat the parse errors. That simply means it's not json.
}
}
}
AntiForgery.Validate(cookie?.Value, token);
}
}
在这些情况下,您无法使用股票验证器验证防伪令牌:
如果您需要执行这些操作中的任何一项,您需要编写自己的防伪检查,以便您可以在传递的数据中找到令牌。 我写了一份防伪检查,执行以下操作: