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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 10:27:09