.NET 6控制台程序调用Identity Server Token Endpoint报400错误排查
问题分析与修复方案
你的代码存在几个关键问题,导致Identity Server返回400 Bad Request错误,以下是具体问题和修正方案:
核心问题
- 请求体格式错误:Identity Server的
/connect/token端点(密码模式)要求请求体采用application/x-www-form-urlencoded格式,而你的代码将数据序列化为JSON并设置Content-Type为application/json,这是触发400错误的主要原因。 - Accept头设置矛盾:你添加了
Accept: application/x-www-form-urlencoded,但Identity Server返回令牌时默认使用JSON格式,这个头设置不仅多余,还可能引发解析冲突。 - HttpClient生命周期问题:频繁创建
HttpClient实例可能导致套接字资源耗尽,建议复用实例或使用.NET推荐的IHttpClientFactory。
修正后的代码
public static async Task<WorkflowResponse> PostRequestToIdentityAsync() { var url = "http://didentity/connect/token"; // 构建表单键值对,符合x-www-form-urlencoded格式要求 var formData = new Dictionary<string, string> { {"username", "csm"}, {"password", "MjAyMjox"}, {"grant_type", "password"}, {"scope", "m_gln m_msd"} }; using (var httpClient = new HttpClient()) { var request = new HttpRequestMessage { Method = HttpMethod.Post, RequestUri = new Uri(url), // 使用FormUrlEncodedContent自动处理正确的Content-Type Content = new FormUrlEncodedContent(formData), Headers = { {"X-Login", "override"} } }; var clientId = "gclt"; var clientSecret = "glsrt"; // 显式设置接受JSON格式响应 httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // 基础认证信息编码 request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"{clientId}:{clientSecret}"))); HttpResponseMessage message = await httpClient.SendAsync(request); if (message.IsSuccessStatusCode) { var contents = await message.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<WorkflowResponse>(contents); } else { throw new Exception(await message.Content.ReadAsStringAsync()); } } }
补充说明
Postman能正常运行,是因为它默认会将表单数据以application/x-www-form-urlencoded格式发送,而非JSON。修正后的代码完全对齐了这个标准请求格式。
如果是长期维护的项目,建议在.NET 6控制台应用中使用IHttpClientFactory管理HttpClient生命周期,避免资源泄漏:
// 在Program.cs中注册 builder.Services.AddHttpClient(); // 通过依赖注入获取IHttpClientFactory后创建实例 var httpClient = _httpClientFactory.CreateClient();
内容的提问来源于stack exchange,提问作者Chamin Thilakarathne
相关产品推荐
相关产品推荐

