I've an ASP.NET core 2.2 MVC app which exposes a Login page with a basic form (username/password). The controller action is protected by the AntiForgeryTokenAttribute
, and the hidden __RequestVerificationToken
is added by MVC.
I'm writing Integration Tests using TestServer and I want to send the form and see if I get 302 status code, but I couldn't find any valid option.
One option I evaluated was to do the GET, extract the __RequestVerificationToken and then submit the tpoken as part of the form. Howerer this won't work as I am missing the cookie (I believe). TestServer.CreateClient
doesn't support any handler, so I can't add cookies.
Is there a way to test this ?
Thanks!
so there are two things needed:
You can extract the token using:
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];
You can extract the __RequestVerification using Nuget package HtmlAgilityPack and then doing:
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();
where htmlContent
is HttpResponse.Content.ReadAsStringAsync();
When you create the form, add the __RequestVerificationToken:
new FormUrlEncodedContent(new List<KeyValuePair<string, string>>
{
... your stuff here
new KeyValuePair<string, string>("__RequestVerificationToken", token)
});
}
then when sending the request:
var request = new HttpRequestMessage(HttpMethod.Post, endPoint)
{ Content = form };
request.Headers.Add("Cookie", $"{cookie.Name}={cookie.Value}");
await client.SendAsync(request);
where client
is HttpClient
created using TestServer.CreateClient
.
Hope this helps somebody else!