Как вызвать методы Web API, имеющие декоратор ValidateAntiForgeryToken
У меня есть веб-API в MVC5 / Web API 2.0. Я пытаюсь вызвать POST метод входа в систему для аутентификации пользователя. Когда я удаляю декоратор [ValidateAntiForgeryToken] из метода входа в систему, консольный клиент, который я написал на C# для вызова веб-методов, работает нормально, но не работает, когда установлен ValidateAntiForgeryToken. Возвращена ошибка: "400: неверный запрос". Теперь я попробовал несколько способов, таких как извлечение токена и куки-файла из ответа на запрос Get, и установка его в запросе, но он не работает.
Я пробовал несколько способов, которые я нашел в Интернете, как:
[HttpPost("sendstring")]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SendString([FromBody]string stData)
{
return View(stData);
}
и еще один:
[HttpGet("thetoken")]
[AllowAnonymous]
public IActionResult TheToken()
{
var tokens = _antiforgery.GetAndStoreTokens(HttpContext);
return new ObjectResult(new
{
token = tokens.RequestToken,
tokenName = tokens.HeaderName
});
}
и, наконец, метод входа в систему, который никогда не вызывается, когда установлен [ValidateAntiForgeryToken]
[HttpPost("login")]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login([FromBody]LoginInfo model)
{
//ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
//return ("User logged in.");
return View();
}
}
return View("If we got this far, something failed, redisplay form");
}
на стороне клиента я делаю что-то вроде этого:
public static async Task RunAsync()
{
// Update port # in the following line.
client.BaseAddress = new Uri("http://localhost:52176/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
try
{
string stResult;
string antiForgeryToken = null;
// The base URL of the API is called to get the Antiforgery token
HttpResponseMessage responseb = await client.GetAsync("/api/default");
if (responseb.IsSuccessStatusCode)
{
antiForgeryToken = await AntiForgeryHelper.ExtractAntiForgeryToken(responseb);
}
var cookies = CookiesHelper.ExtractCookiesFromResponse(responseb);
responseb.EnsureSuccessStatusCode();
// New Code to send request with Anti forgery
// Serialize data to Key/Value pairs
//IDictionary<string, string> contentData = content.ToKeyValue();
//IDictionary<string, string> contentData = new
var contentData = new Dictionary<string, string>
{
{"__RequestVerificationToken", antiForgeryToken},
{"Email", "a@a.com"},
{"Password", "TestPass"}
};
// Using abstract methods now
string antiForgeryTokena = await AntiForgeryHelper.ExtractAntiForgeryToken(responseb);
var formPostBodyData = new Dictionary<string, string>
{
{"__RequestVerificationToken", antiForgeryTokena}, // Add token
{"Email", "a@a.com"},
{"Password", "Password" },
{"RememberMe", "true" }
};
var requestMessage = PostRequestHelper.CreateWithCookiesFromResponse("/Account/Login", formPostBodyData, responseb);
requestMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
requestMessage.Content.Headers
var responsepp = await client.PostAsJsonAsync("api/default/Login", requestMessage);
if (responsepp.IsSuccessStatusCode)
{
stResult = await responsepp.Content.ReadAsAsync<string>();
}
}
Функции "CreateWithCookiesFromResponse" и "ExtractAntiForgeryToken" взяты из блога Стефана Хендрика. Хотя я использовал эти функции, как он, но безрезультатно: http://www.stefanhendriks.com/2016/05/11/integration-testing-your-asp-net-core-app-dealing-with-anti-request-forgery-csrf-formdata-and-cookies/