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

ASP.NET Core 6应用使用Negotiate认证时的握手错误

ASP.NET Core 6 Negotiate认证生产环境500错误排查

问题背景

我有一个ASP.NET Core 6应用,使用Negotiate认证方案通过Windows身份验证(NTLM/Kerberos)完成身份验证。本地开发机器上配置运行正常,但部署到生产服务器后出现问题:调用标记了[Authorize]的端点时,浏览器弹出登录提示,输入凭证后后端返回500错误。

关键现象:服务器内部通过https://localhost访问应用时认证正常;使用完整机器URL(如https://myserver.domain.local)访问时认证失败并返回500错误。

认证配置代码

services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate();
    
services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder(NegotiateDefaults.AuthenticationScheme)
        .RequireAuthenticatedUser()
        .Build();
}

错误日志信息

Connection id "0HN6OHVHNEJKS", Request id "0HN6OHVHNEJKS:00000007": An unhandled exception was thrown by the application.
System.InvalidOperationException: An anonymous request was received in between authentication handshake requests.
at Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.HandleException(HttpContext context, ExceptionDispatchInfo edi)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

排查与解决思路

1. 检查代理/负载均衡的请求转发配置

由于localhost访问正常、域名访问失败,大概率是代理或负载均衡中断了NTLM/Kerberos的握手流程:

  • 确保代理(IIS、Nginx等)保留原始请求头,特别是Authorization头,同时启用客户端IP传递
  • 若使用IIS反向代理,关闭WebDAV模块或配置允许认证请求通过,避免拦截OPTIONS等预请求
  • 负载均衡需启用粘性会话,NTLM/Kerberos握手需要同一个连接完成多轮请求,分散到不同实例会导致握手中断

2. 验证Kerberos/NTLM服务端配置

  • 若使用Kerberos,检查服务器SPN(服务主体名称)注册是否正确:执行setspn -L <服务器运行账号>,确认存在HTTP/myserver.domain.local和HTTP/myserver的SPN
  • 应用池运行账号需为域账号(本地账号仅支持NTLM),且拥有读取SPN的权限
  • 检查本地安全策略:网络安全: LAN管理器身份验证级别设置为兼容客户端的级别(如发送NTLMv2响应\拒绝LM & NTLM)

3. 抓包与日志调试

  • 用Fiddler或Wireshark抓包,对比localhost和域名访问的请求差异:查看是否在握手过程中出现额外匿名请求(如浏览器自动发送的OPTIONS请求),以及认证头是否正确传递
  • 开启详细认证日志,在appsettings.json中添加:
{
  "Logging": {
    "LogLevel": {
      "Microsoft.AspNetCore.Authentication": "Trace",
      "Microsoft.AspNetCore.Server.Kestrel": "Trace"
    }
  }
}

通过日志追踪认证握手的每一步,定位匿名请求的来源。

4. 调整中间件顺序

从堆栈日志看SessionMiddleware在认证中间件之后执行,可能干扰认证状态传递。确保中间件顺序符合官方规范:

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication(); // 认证中间件优先于Session
app.UseAuthorization();
app.UseSession(); // Session中间件放在认证之后

5. 临时禁用非必要中间件

暂时移除SessionMiddleware或其他非核心中间件,测试认证是否恢复正常。若恢复,再逐步排查该中间件的配置问题(如Session Cookie的SameSite设置、超时时间等)。


内容的提问来源于stack exchange,提问作者Master_T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:27:27