ASP.NET Core HttpClient For Antiforgery
2024-07-19
筆記 ASP.NET Core 如何對有 AntiForgery 的網站進行 POST 操作。
說明
Post 的重點:
- 要使用
UseDefaultCredentials = true
來使用 Windows 認證 - 加入
User-Agent
來模擬瀏覽器連線 - 使用
FormUrlEncodedContent
來傳送表單資料及 - 要包含 Cookie ,透過
DefaultRequestHeaders.Add("Cookie", "key=value")
設定
其中針對 Antiforgery
的處理,需要加在 FormUrlEncodedContent
中,並且在 Cookie
中加入 __RequestVerificationToken
的值。
using Microsoft.Extensions.Configuration;
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();
var handler = new HttpClientHandler()
{
UseDefaultCredentials = true
};
using (var client = new HttpClient(handler))
{
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0");
// load url from appsettings.json
var requestUri = configuration["Url"];
var payload = new Dictionary<string, string>
{
{ "__RequestVerificationToken", configuration["RequestVerificationToken"]! },
{ "Name", DateTime.Now.ToString() },
{ "ReserveDate", "2024-07-17T10:58" }
};
var cookies = new Dictionary<string, string>
{
{"__RequestVerificationToken", configuration["Cookie_RequestVerificationToken"]! }
};
// cookies for client
foreach (var cookie in cookies)
{
client.DefaultRequestHeaders.Add("Cookie", $"{cookie.Key}={cookie.Value}");
}
while (true)
{
var request = new HttpRequestMessage(HttpMethod.Post, requestUri);
request.Content = new FormUrlEncodedContent(payload);
var response = await client.SendAsync(request);
//response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
Thread.Sleep(500);
}
}
{
"RequestVerificationToken": "0LmfCm9oFkX01",
"Url": "https://localhost:44347/Reserves/Create",
"Cookie_RequestVerificationToken": "bXSJUHahvaIRdsgY1"
}
搭配的 Controller 如下:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name,ReserveDate")] Reserve reserve)
{
string key = System.Configuration.ConfigurationManager.AppSettings["open"];
if (key == "false")
{
return Content("System is closed");
}
if (ModelState.IsValid)
{
db.Reserve.Add(reserve);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(reserve);
}