.net Core 2.0 web api 400 error using Validateantiforgerytoken
.net Core 2.0 web api 400 error using Validateantiforgerytoken
我有两个 .Net Core 应用程序,一个 Web API 和一个客户端。使用 :
从客户端发送 Post
<form asp-action="Create" method="post">
@Html.AntiForgeryToken()
.....
</form>
客户端控制器:
public async Task<IActionResult> Create([Bind("QuestionId,TheQuestion")] SecurityQuestion securityQuestion)
{
_session.SetString(SessionsKeys.Directory, "/SecurityQuestions");
if (ModelState.IsValid)
{
var data = await _theService.PostWebApi(securityQuestion);
if (data.Item3 == "True")
{
return RedirectToAction(nameof(Index));
}
return View(data.Item1);
}
return View(securityQuestion);
}
与网络通信的方法API:
public async Task<(object, string, string)> PostWebApi(TObject model)
{
var dir = _session.GetString(SessionsKeys.Directory);
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(_webApiData.WebApiitems.Url);
MediaTypeWithQualityHeaderValue contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
string stringData = JsonConvert.SerializeObject(model);
var contentData = new StringContent(stringData, System.Text.Encoding.UTF8, "application/json");
HttpResponseMessage response = client.PostAsync(dir + "/", contentData).Result;
var msg = await response.Content.ReadAsStringAsync();
var theresponse = response.IsSuccessStatusCode.ToString();
return (model,msg,theresponse);
}
}
Web API 控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> PostSecurityQuestion([FromRoute] SecurityQuestion securityQuestion)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.SecurityQuestion.Add(securityQuestion);
await _context.SaveChangesAsync();
return CreatedAtAction("GetSecurityQuestion", new { id = securityQuestion.QuestionId }, securityQuestion);
}
如果我删除 [ValidateAntiForgeryToken]
,它会起作用。我也尝试删除 [Form]
,但我仍然收到 400 错误。
我是否遗漏了启动配置中的任何其他设置?
在Startup.cs
文件里面ConfigureServices()
方法下面添加服务
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
防伪令牌用于确保您的客户提交的表单是您发布的表单---也就是说,它不是伪造的。
在您的例子中,您的客户端应用程序正在通过 @Html.AntiForgeryToken()
生成自己的防伪令牌。但是,它不会传递给您创建的 HttpClient
来与您的 Web API 对话。但是,即使您设法将该防伪令牌传递给您的 Web API,它也可能会被拒绝,因为它不是由 Web API.
颁发的
您应该更改您的网站 API 以允许您的客户获得令牌。这是斯科特·艾伦 (Scott Allen) 关于如何做到这一点的博客:
我有两个 .Net Core 应用程序,一个 Web API 和一个客户端。使用 :
从客户端发送 Post<form asp-action="Create" method="post">
@Html.AntiForgeryToken()
.....
</form>
客户端控制器:
public async Task<IActionResult> Create([Bind("QuestionId,TheQuestion")] SecurityQuestion securityQuestion)
{
_session.SetString(SessionsKeys.Directory, "/SecurityQuestions");
if (ModelState.IsValid)
{
var data = await _theService.PostWebApi(securityQuestion);
if (data.Item3 == "True")
{
return RedirectToAction(nameof(Index));
}
return View(data.Item1);
}
return View(securityQuestion);
}
与网络通信的方法API:
public async Task<(object, string, string)> PostWebApi(TObject model)
{
var dir = _session.GetString(SessionsKeys.Directory);
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(_webApiData.WebApiitems.Url);
MediaTypeWithQualityHeaderValue contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
string stringData = JsonConvert.SerializeObject(model);
var contentData = new StringContent(stringData, System.Text.Encoding.UTF8, "application/json");
HttpResponseMessage response = client.PostAsync(dir + "/", contentData).Result;
var msg = await response.Content.ReadAsStringAsync();
var theresponse = response.IsSuccessStatusCode.ToString();
return (model,msg,theresponse);
}
}
Web API 控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> PostSecurityQuestion([FromRoute] SecurityQuestion securityQuestion)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.SecurityQuestion.Add(securityQuestion);
await _context.SaveChangesAsync();
return CreatedAtAction("GetSecurityQuestion", new { id = securityQuestion.QuestionId }, securityQuestion);
}
如果我删除 [ValidateAntiForgeryToken]
,它会起作用。我也尝试删除 [Form]
,但我仍然收到 400 错误。
我是否遗漏了启动配置中的任何其他设置?
在Startup.cs
文件里面ConfigureServices()
方法下面添加服务
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
防伪令牌用于确保您的客户提交的表单是您发布的表单---也就是说,它不是伪造的。
在您的例子中,您的客户端应用程序正在通过 @Html.AntiForgeryToken()
生成自己的防伪令牌。但是,它不会传递给您创建的 HttpClient
来与您的 Web API 对话。但是,即使您设法将该防伪令牌传递给您的 Web API,它也可能会被拒绝,因为它不是由 Web API.
您应该更改您的网站 API 以允许您的客户获得令牌。这是斯科特·艾伦 (Scott Allen) 关于如何做到这一点的博客: