You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7中使用Basic Auth调用Web API时出现Forbidden错误排查

.NET 7调用Basic Auth API返回403 Forbidden的排查与解决

问题背景

我正在测试一个API,地址为https://imunizacao-es.saude.gov.br/_search,采用Basic Auth认证,凭证信息如下:

登录名:immunizacao_public,密码:qlto5t&7r_@+#Tlstigi

相同的筛选逻辑在Postman中可正常运行,但在我的.NET 7项目中测试时却返回Forbidden错误。我需要获取该API返回的接种总人数,相关代码如下:

private readonly string _searchUrl = "https://imunizacao-es.saude.gov.br/_search";
private readonly string _username = "imunizacao_public";
private readonly string _password = "qlto5t&7r_@+#Tlstigi";

private async Task<int> ObtainTotalNumberVaccinated(DateTime applicationDate)
{
    using (HttpClient httpClient = new HttpClient())
    {
        //Set authentication credentials
        string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{_username}:{_password}"));
       
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);

        // Build the body of the request to get the total number of vaccinated
        string requestBody = @"{
            ""query"": {
                ""bool"": {
                    ""must"": [
                        {
                            ""match"": {
                                ""vacina_fabricante_nome"": ""PFIZER""
                            }
                        },
                        {
                            ""match"": {
                                ""estabelecimento_uf"": ""RJ""
                            }
                        },
                        {
                            ""match"": {
                                ""vacina_dataAplicacao"": """ + applicationDate.ToString("yyyy-MM-dd") + @"""
                            }
                        }
                    ]
                }
            }
        }";
        HttpContent content = new StringContent(requestBody, Encoding.UTF8, "application/json");

        //Send POST request to get the total amount vaccinated
        HttpResponseMessage response = await httpClient.PostAsync(_searchUrl, content);
        string responseContent = await response.Content.ReadAsStringAsync();

        // Parse the response content to get the total vaccinated count
        dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent);
        int TotalNumberVaccinated = jsonResponse.hits.total.value;
        return totalNumberVaccinated;
    }
}

可能原因与解决办法

1. 密码特殊字符编码问题

密码包含&、#等特殊字符,直接用Encoding.ASCII拼接可能导致编码异常。Postman会自动处理特殊字符的URL编码,而手动拼接时容易遗漏。

修正方式:改用Encoding.UTF8生成Base64凭证,确保特殊字符正确编码:

string credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{_username}:{_password}"));

2. HttpClient实例化方式问题

每次创建新的HttpClient实例会导致连接无法复用,且可能丢失默认请求头配置。Postman默认复用连接,而频繁创建实例可能触发API的限流或认证校验逻辑。

修正方式:将HttpClient改为静态单例,复用实例:

private static readonly HttpClient _httpClient = new HttpClient();

// 方法内不再创建新的HttpClient实例,直接使用_httpClient

3. 请求体字符串拼接的潜在错误

直接拼接JSON字符串可能因日期格式的文化差异(如系统默认日期格式不是yyyy-MM-dd)导致请求体格式错误,触发API的校验拦截。

修正方式:用匿名对象构建请求体后序列化,避免拼接错误:

var requestBody = new
{
    query = new
    {
        @bool = new
        {
            must = new[]
            {
                new { match = new { vacina_fabricante_nome = "PFIZER" } },
                new { match = new { estabelecimento_uf = "RJ" } },
                new { match = new { vacina_dataAplicacao = applicationDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) } }
            }
        }
    }
};
var jsonContent = JsonConvert.SerializeObject(requestBody);
HttpContent content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

4. 额外排查点

  • 抓包对比请求差异:用Fiddler或Wireshark对比Postman与.NET请求的Authorization头、请求体是否完全一致,确认认证凭证是否正确。
  • 检查代理/防火墙:.NET程序可能受系统代理或防火墙限制,导致请求被拦截,Postman可能使用了不同的代理配置。
  • 确认IP访问限制:部分API会限制请求来源IP,Postman的公网IP可能被允许,而服务器IP被拒绝。

内容的提问来源于stack exchange,提问作者Rafaela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:23:11