TestServer和HttpClient在.net核心Web api中获取Badfor for forforgey令牌

问题描述 投票:1回答:1

我在从xUnit测试项目中调用默认端点'/ api / values时遇到问题。 Web api是默认的.net核心项目。我总是收到不好的请求-400甚至在每个请求上都添加了带有AF cookie值的标头。

首先我在启动类中设置了防伪。

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 Coo​​kie的AF Coo​​kie获取值

  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
1个回答
0
投票
发生的情况是,浏览器或诸如postman之类的调试工具中的cookie会在收到后自动存储,然后随其后的每个请求一起发送到与它们具有相同域的URL。当您尝试用代码编写和发出请求时,情况并非如此。
© www.soinside.com 2019 - 2024. All rights reserved.