.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
相关产品推荐
相关产品推荐

