ASP.NET Core 3.1 Windows身份认证下非浏览器请求返回401问题
问题描述
使用Insomnia、curl或通过httpContext.GetAsync(url);等方式访问接口时收到401 Unauthorized错误,但Edge、Chrome等常规浏览器可正常访问。
作为Web开发新手,我正在用ASP.NET Core 3.1开发一个读取Excel文件并保存内容到数据库的简单Web应用,需要通过Windows用户名(PC-Name\LoginName)填充CreatedBy字段,无需显式登录页面。应用仅在封闭网络中使用,所有Windows用户均已在网络注册,只需获取当前登录用户ID即可。
浏览器访问接口可正常返回PC-Name\LoginName,但非浏览器客户端及内部API调用均返回401,即使复制浏览器请求头也无效。
相关代码文件
Startup.cs
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication.Negotiate; namespace TestingWebAPI { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate(); services.AddAuthorization(options => { options.FallbackPolicy = options.DefaultPolicy; }); services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
Controller代码
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace TestingWebAPI.Controllers { [Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { [HttpGet] [Route("{action}")] public string GetCurrentUser() { return HttpContext.User.Identity.Name; } } }
launchSettings.json
{ "$schema": "http://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": true, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:60085", "sslPort": 44323 } }, "profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "launchUrl": "weatherforecast", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "TestingWebAPI": { "commandName": "Project", "launchBrowser": true, "launchUrl": "weatherforecast", "applicationUrl": "https://localhost:5001;http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
浏览器请求头
GET /api/Values/GetCurrentUser HTTP/1.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate, br, zsdch Accept-Language: en-US,en;q=0.9 Cache-Control: max-age=0 Connection: keep-alive Cookie: csrftoken=gy4oKWvUo9WRpaaWMgp6DiFuTZnfUsTb DNT: 1 Host: localhost:44323 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.183 sec-ch-ua: "Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows"
解决方案
当前使用的是Negotiate身份验证(支持NTLM/Kerberos协议),浏览器会自动调用Windows系统的身份验证组件,使用当前登录用户的凭证完成认证流程,但非浏览器客户端不会自动触发这个逻辑,需要手动配置传递Windows凭证:
1. curl访问配置
在curl命令中添加--ntlm参数并指定使用当前用户凭证:
curl --ntlm -u : https://localhost:44323/api/Values/GetCurrentUser
-u :表示直接使用当前Windows登录用户的凭证,无需手动输入用户名和密码。
2. Insomnia访问配置
在Insomnia的请求设置中:
- 切换到Auth标签页
- 认证类型选择NTLM
- 可留空用户名和密码(自动使用当前Windows用户),也可手动输入
PC-Name\LoginName及对应密码
3. 内部API调用(HttpClient方式)
发送请求时需要配置HttpClientHandler启用默认凭证:
var handler = new HttpClientHandler { UseDefaultCredentials = true // 自动使用当前Windows用户的凭证 }; using var client = new HttpClient(handler); var response = await client.GetAsync("https://localhost:44323/api/Values/GetCurrentUser"); var content = await response.Content.ReadAsStringAsync();
额外配置说明
- 应用需运行在Windows环境下,Negotiate认证依赖Windows系统的身份验证服务
- 若网络使用Kerberos协议,需确保服务主体名称(SPN)配置正确,否则会自动降级到NTLM
- 直接运行Kestrel时默认未启用Windows认证,需在
launchSettings.json的TestingWebAPI配置中添加环境变量:"TestingWebAPI": { "commandName": "Project", "launchBrowser": true, "launchUrl": "weatherforecast", "applicationUrl": "https://localhost:5001;http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_Kestrel__WindowsAuthentication__Enabled": "true" } }
内容的提问来源于stack exchange,提问作者Balaji
相关产品推荐
相关产品推荐

