I had written a web performance test which was earlier working fine. Developers now have added a CSRF token validation (to prevent CSRF attack on the website). After this the test has started to fail (Error, Bad Request). I dug into it and found that the server is generating an XSRF-TOKEN on login request which has to be passed in every request there after. Now to extract the token we need to parse response to the login request. How can we do it?
My coded tests looks like this:
WebTestRequest request4 = new WebTestRequest("https://servertest:8080/WebConsole/Account/Login");
request4.Method = "POST";
request4.Headers.Add(new WebTestRequestHeader("Accept", "application/json, text/plain, */*"));
request4.Headers.Add(new WebTestRequestHeader("Referer", "https://servertest:8080/WebConsole/index.html#/"));
StringHttpBody request4Body = new StringHttpBody();
request4Body.ContentType = "application/json;charset=utf-8";
request4Body.InsertByteOrderMark = false;
request4Body.BodyString = "{\"UserName\":\"pkdomain\\\\administrator\",\"Password\":\"sqa@123\"}";
request4.Body = request4Body;
yield return request4;
request4 = null;
WebTestRequest request5 = new WebTestRequest("https://servertest:8080/WebConsole/scripts/home/Pages/home-view.html");
request5.ThinkTime = 4;
request5.Headers.Add(new WebTestRequestHeader("Accept", "text/html"));
request5.Headers.Add(new WebTestRequestHeader("Referer", "https://servertest:8080/WebConsole/index.html#/"));
yield return request5;
request5 = null;
I believe the XSRF-TOKEN
is returned in a cookie. Assuming that this is true in your case then the Set-Cookie
header field contains the value and the required cookie must be extracted from it and saved to a context parameter. Subsequently that context parameter can be used wherever needed.
I suggest you create a sandbox .webtest
file, do the steps below then convert it to coded test and copy the useful lines into the real test.
In more detail the steps are:
Add an Extract HTTP Header
extraction rule for the Set-Cookie
header field to the request that returns the XSRF-TOKEN
value. Save the extracted value to a context parameter of your choice, give its name in one of the properties of the extraction rule; see the image below.
Add a call of the plugin below to the first request after the one with the above extraction rule. It extracts the required field from the cookie header field. The image below shows setting the properties of the call. (You might change the plugin to be a PostRequest
and add it to the same request as the one with the extraction rule.)
public class ExtractCookieField : WebTestRequestPlugin
{
public string AllCookiesCP { get; set; }
public string FieldWantedCP { get; set; }
public string SavedFieldCP { get; set; }
// Expected to be called with AllCookiesCP containing text similar to:
// SomeHeader=639025785406236250; path=/; XSRF-TOKEN=somestring; secure; HttpOnly
public override void PreRequestDataBinding(object sender, PreRequestDataBindingEventArgs e)
{
string AllCookiesText = e.WebTest.Context[AllCookiesCP].ToString();
foreach (string nameValuePair in AllCookiesText.Split(';'))
{
string[] nameAndValue = nameValuePair.Split(new char[] { '=' }, 2);
if (nameAndValue[0].Trim() == FieldWantedCP)
{
string sessionTokenId = nameAndValue[1].Trim();
e.WebTest.Context[SavedFieldCP] = sessionTokenId;
e.WebTest.AddCommentToResult(string.Format("Setting {{{0}}} to '{1}'", SavedFieldCP, sessionTokenId));
return;
}
}
// Dropping out of the loop means that the field was not found.
throw new WebTestException(string.Format("Cannot extract cookie field '{0}' from '{1}'", FieldWantedCP, AllCookiesText));
}
}
The value of the XSRF-TOKEN
should now be in the context parameter specified in the SavedFieldCP
property of the plugin call.
This image shows the add extraction rule dialogue and setting the context parameter where the extracted header field is saved, ie into CookieValues
. It also show the add plugin and setting the three properties. After the plugin runs, assuming it is successful, the token value should be saved into the context parameter XsrfToken
. The parameter values can be modified in the .webtest
file via the properties panels of the extraction rule and the plugin. The values should also be clearly seen as simple variables and strings in a coded webb test.