Как обойти проверку токена антиподделения на посте формы в интеграционных тестах - PullRequest
0 голосов
/ 24 октября 2019

У меня есть приложение ASP.NET core 2.2 MVC, которое предоставляет страницу входа в виде базовой формы (имя пользователя / пароль). Действие контроллера защищено AntiForgeryTokenAttribute, а MVC добавляет скрытое __RequestVerificationToken.

Я пишу интеграционные тесты с использованием TestServer и хочу отправить форму и посмотреть, получу ли я статус 302кода, но я не смог найти ни одной действительной опции.

Один из вариантов, который я оценил, заключался в том, чтобы выполнить GET, извлечь __RequestVerificationToken и затем отправить tpoken как часть формы. Как бы то ни было, это не сработает, так как мне не хватает куки (я верю). TestServer.CreateClient не поддерживает какой-либо обработчик, поэтому я не могу добавить куки.

Есть ли способ проверить это?

Спасибо!

1 Ответ

0 голосов
/ 04 ноября 2019

, поэтому необходимо две вещи:

  1. во время страницы GET: получить cookie из заголовков и извлечь __RequestVerification
  2. при отправке формы: добавить cookie вЗаголовки и добавьте __RequestVerification к модели

1. GET

Вы можете извлечь токен с помощью:

headers.FirstOrDefault(x => x.Key == "Set-Cookie").Value.First().Split(" ")[0];

// The cookie we are looking for is .AspNetCore.Antiforgery.<unique guid>=<unique guid>
var tokenCookie = cookieContent.Split("=");
var name = tokenCookie[0];
var value = tokenCookie[1];

Вы можете извлечь __RequestVerification с помощью пакета Nuget HtmlAgilityPack , а затем выполнить:

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(htmlContent);
var tokenValue = htmlDoc.DocumentNode.SelectSingleNode("//input[@name='__RequestVerificationToken']")
                .Attributes.Where(x => x.Name == "value").Select(x => x.Value).First();

где htmlContent равно HttpResponse.Content.ReadAsStringAsync();

2. POST

Когда вы создаете форму, добавьте __RequestVerificationToken:

new FormUrlEncodedContent(new List<KeyValuePair<string, string>>
{
    ... your stuff here
    new KeyValuePair<string, string>("__RequestVerificationToken", token)
        });
}

, а затем при отправке запроса:

var request = new HttpRequestMessage(HttpMethod.Post, endPoint)
{ Content = form };

request.Headers.Add("Cookie", $"{cookie.Name}={cookie.Value}");

await client.SendAsync(request);

, где client - HttpClient созданиспользуя TestServer.CreateClient.

Надеюсь, это поможет кому-то еще!

...