Как вызвать методы 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/

0 ответов

Другие вопросы по тегам