使用Bearer Token调用HttpClient返回401未授权问题排查
问题分析:.NET 6文件上传接口返回401未授权的原因
核心错误:请求头未被正确发送
问题代码的关键失误在于:你构造了HttpRequestMessage并添加了Authorization和api-version头,但最终调用client.PostAsync(uploadUrl, content)时,这个方法会完全忽略你之前创建的HttpRequestMessage对象,而是生成一个全新的POST请求发送,导致你设置的授权头和版本头都没有被传递到服务器,因此返回401未授权。
次要问题:地址配置冗余
问题代码中给HttpClient设置了BaseAddress,但又给HttpRequestMessage指定了完整的uploadUrl作为RequestUri,这不仅让BaseAddress的配置失去意义,还可能引发地址拼接的潜在问题。
修正代码的关键改进点
修正后的代码针对性解决了这些问题:
- 将
Authorization头添加到client.DefaultRequestHeaders,确保该客户端发送的所有请求都会自动携带授权信息; - 采用
BaseAddress+ 相对路径("uploads")的方式构造请求地址,避免地址冗余; - 通过
client.SendAsync(request)发送预先构造好的HttpRequestMessage,确保api-version等自定义头被正确携带; - 将请求内容赋值给
request.Content后再发送,保证请求的完整性。
问题代码
private static async Task UploadCsvFileAsync(string authToken) { using (var client = new HttpClient()) { client.BaseAddress = new Uri("https://subdomain.domain.com/"); client.DefaultRequestHeaders .Accept .Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); using (var request = new HttpRequestMessage()) { request.RequestUri = new Uri(uploadUrl); request.Method = HttpMethod.Post; request.Headers.Add("api-version", "1"); request.Headers.Add("Authorization", $"Bearer {authToken}"); string header = $"{Environment.NewLine}--{formBoundary}{Environment.NewLine}" + $"Content-Disposition: form-data; name=\"csvfile\"; filename=\"{csvFileName}\"{Environment.NewLine}" + $"Content-Type: text/csv{Environment.NewLine}{Environment.NewLine}"; byte[] headerBytes = Encoding.UTF8.GetBytes(header); var headerContent = new StreamContent(new MemoryStream(headerBytes)); headerContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream"); var content = new MultipartFormDataContent(); content.Add(headerContent, "metadata", csvFileName); var response = await client.PostAsync(uploadUrl, content); // the response code is 401 - Unauthorized } } }
修正后的可行代码
private static async Task UploadCsvFileAsyncV2(string authToken) { using (var client = new HttpClient()) { client.BaseAddress = new Uri(uploadUrl); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken); client.DefaultRequestHeaders .Accept .Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); using (var request = new HttpRequestMessage(HttpMethod.Post, "uploads")) { request.Headers.Add("api-version", "1"); string header = $"{Environment.NewLine}--{formBoundary}{Environment.NewLine}" + $"Content-Disposition: form-data; name=\"csvfile\"; filename=\"{csvFileName}\"{Environment.NewLine}" + $"Content-Type: text/csv{Environment.NewLine}{Environment.NewLine}"; byte[] headerBytes = Encoding.UTF8.GetBytes(header); var headerContent = new StreamContent(new MemoryStream(headerBytes)); headerContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream"); var content = new MultipartFormDataContent { { headerContent, "metadata", csvFileName } }; request.Content = content; var response = await client.SendAsync(request); } } }
内容的提问来源于stack exchange,提问作者OneClutteredMind
相关产品推荐
相关产品推荐

