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

Kestrel承载的C#应用Windows认证仅localhost可用求助

问题描述

我有一个基于Kestrel承载的C# Web应用,启用了Windows身份验证。目前仅使用localhost访问端点时正常,使用IP地址、主机名或127.0.0.1访问会返回401响应,浏览器弹出登录对话框。我需要让主机名或IP地址也能正常访问,且不想使用IIS或HTTP.SYS。

我已尝试调用setspn注册Web应用,但无效果:

setspn -S HTTP/server.development.local development\x

服务器完整域名(FQDN):server.development.local
用户名:development\x

现有代码如下:

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
        builder.Services.AddAuthorization(options =>
        {
            options.FallbackPolicy = options.DefaultPolicy;
        });

        builder.Services.AddControllers();
        builder.WebHost.ConfigureKestrel(serverOptions =>
        {
            serverOptions.ListenAnyIP(60100);
        });

        var app = builder.Build();

        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });

        app.Run();
    }
}

HelloController.cs

[Authorize]
[ApiController]
[Route("[controller]")]
public class HelloController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        var user = HttpContext.User?.Identity?.Name ?? "N/A";

        return Ok(user);
    }
}
解决方案

要让Kestrel承载的应用支持通过主机名/IP进行Windows身份验证,需从以下几方面调整:

1. 补全SPN注册

仅注册主机名的SPN不足以覆盖IP和127.0.0.1的访问场景,需添加对应SPN:

# 替换为你的服务器实际IP
setspn -S HTTP/192.168.1.100 development\x
# 为127.0.0.1注册SPN
setspn -S HTTP/127.0.0.1 development\x

执行完成后,用setspn -L development\x确认所有SPN已成功添加。

2. 配置Negotiate中间件允许的主机

默认情况下Negotiate中间件仅信任localhost请求,需显式添加允许的主机名/IP:
修改Program.cs中AddNegotiate的配置:

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate(options =>
    {
        options.AllowedHosts.Add("server.development.local");
        options.AllowedHosts.Add("192.168.1.100"); // 替换为服务器实际IP
        options.AllowedHosts.Add("127.0.0.1");
    });

3. 客户端侧配置

  • 浏览器访问:将目标主机名/IP添加到浏览器的「本地Intranet站点」列表,避免弹出登录框(以Edge为例:设置 -> 隐私、搜索和服务 -> 安全 -> 本地Intranet -> 添加站点)。
  • 代码调用:如果是HttpClient等客户端调用,需启用默认凭据:
var handler = new HttpClientHandler { UseDefaultCredentials = true };
var client = new HttpClient(handler);
var response = await client.GetAsync("http://server.development.local:60100/Hello");

验证操作

  1. 重启Web应用使配置生效;
  2. 用主机名/IP访问http://server.development.local:60100/Hello,确认能正常返回当前登录用户名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:17:32