【发布时间】:2023-03-07 17:45:01
【问题描述】:
我在从 xUnit 测试项目调用默认端点“/api/values”时遇到问题。 Web api 是默认的 .net 核心项目。我总是收到错误的请求 - 400,即使我在每个请求上添加带有 AF cookie 值的标头。
首先我在 Startup 类中设置防伪。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(
opt =>
{
opt.Filters.Add(new ValidateAntiForgeryTokenAttribute());
}
).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN";
});
}
然后添加单独的控制器和动作来创建 AF cookie
[IgnoreAntiforgeryToken]
[AllowAnonymous]
[HttpGet("antiforgery")]
public IActionResult GenerateAntiForgeryTokens()
{
//generate the tokens/cookie values
//it modifies the response so that the Set-Cookie statement is added to it (that’s why it needs HttpContext as an argument).
var tokens = _antiForgery.GetAndStoreTokens(HttpContext);
Response.Cookies.Append("XSRF-REQUEST-TOKEN", tokens.RequestToken, new CookieOptions
{
HttpOnly = false,
});
return NoContent();
}
然后我设置测试类
public UnitTest1()
{
_server = new TestServer(
WebHost.CreateDefaultBuilder()
.ConfigureAppConfiguration((builderContext, config) =>
{
config.AddJsonFile("appsettings.test.json", optional: false, reloadOnChange: true);
})
.UseStartup<Startup>()
.UseEnvironment("Development")
);
_client = _server.CreateClient();
_client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
}
并在测试类中添加方法以从 AF cookie 中获取 AF 标头的值
protected async Task<string> EnsureAntiforgeryToken()
{
string _antiforgeryToken = string.Empty;
var response = await _client.GetAsync("/api/AntiForgery/antiforgery");
response.EnsureSuccessStatusCode();
if (response.Headers.TryGetValues("Set-Cookie", out IEnumerable<string> values))
{
var _antiforgeryCookie = Microsoft.Net.Http.Headers.SetCookieHeaderValue.ParseList(values.ToList()).SingleOrDefault(c => c.Name.StartsWith(XSRF_TOKEN, StringComparison.InvariantCultureIgnoreCase));
_antiforgeryToken = _antiforgeryCookie.Value.ToString();
}
return await Task.FromResult<string>(_antiforgeryToken);
}
在我的测试方法中我尝试调用端点
[Fact]
public async Task Test1Async()
{
_antiforgeryCookie = await EnsureAntiforgeryToken();
_client.DefaultRequestHeaders.Add("X-XSRF-TOKEN", _antiforgeryCookie);
var result = await _client.GetAsync("/api/values"); //always get error 400
Assert.True(true, "");
}
【问题讨论】:
标签: httpclient antiforgerytoken bad-request