0

我正在尝试将 net core 3 API 作为 Windows 服务(即不使用 IIS)运行,并在活动目录上使用 Http.Sys 身份验证帐户。我想启用基本身份验证(必须支持开发人员要求基本身份验证的非 .NET 语言),但在可用的情况下允许 windows/kerberos。

我大部分时间都在那里,事实上我基本上有一个服务可以做我想做的一切,除了一件事 - 我只看到使用 NTLM 而不是 kerberos。我可能会按原样去生产,但我想了解为什么我不能让 kerberos 工作。我相信最后一块是SPN。

创造:

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        return Host.CreateDefaultBuilder(args)
                   .ConfigureServices((hostContext, services) =>
                   {
                       services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);
                       services.AddHostedService<Worker>();
                   })
                   .ConfigureWebHostDefaults(webBuilder =>
                   {
                       webBuilder.UseHttpSys(options =>
                       {
                           options.Authentication.Schemes = AuthenticationSchemes.Basic | AuthenticationSchemes.Negotiate;
                           options.Authentication.AllowAnonymous = true;
                           options.UrlPrefixes.Add("https://*:20010/");
                       });
                       webBuilder.UseStartup<Startup>();
                   })
                   .UseWindowsService();
    }

启动类:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers().AddJsonOptions(opts =>
        {
            opts.JsonSerializerOptions.IgnoreNullValues = true;
            opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

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

控制器:

[ApiController]
[Route("test")]
[Authorize]
public class TestController : ControllerBase
{
    [HttpGet("run")]
    public ContentResult Run()
    {
        return new ContentResult
        {
            Content = $"Run Requested: {string.Join(",", this.User?.Identity?.Name, this.User?.Identity?.IsAuthenticated, this.User?.Identity?.AuthenticationType)}",
        };
    }
}

我已经支付了正确的证书,我在 ps1 脚本中使用 netsh 在端口 20010 上设置了该证书:

 $guid = [guid]::NewGuid()
 $certHash = "<CORRECT THUMBNAIL>"
 $ip = "0.0.0.0" # This means all IP addresses
 $port = "20010" # the default HTTPS port
 "http add sslcert ipport=$($ip):$port certhash=$certHash appid={$guid}" | netsh

网络服务器:

  • 正确加入域
  • netbios 名称:mywebserver
  • 全名:mywebserver.ad.mydomain.com

服务:

  • .net 核心 3.1
  • 在域帐户“myserviceaccount”下运行

服务帐户“myserviceaccount”当前在 Web 服务器上具有管理员权限,如果我将证书权限直接授予此帐户,我想我可以删除它。或者也许要让这一切正常工作,我必须将其作为系统帐户运行?不过最好不要这样做。

活动目录:

  • ad.mydomain.com
  • 服务器 netbios 名称:domainserver
  • 服务器全名:domainserver.ad.mydomain.com

照原样,这适用于所有浏览器/操作系统以及设置为使用该服务的所有语言。它正确地挑战,允许域用户通过并显示正确的证书。但如上所述,当我使用各种身份验证测试器/提琴手等时 - 它仅在从 Windows 客户端访问时显示 NTLM。

我尝试在 Web 服务器上设置以下 SPN:

setspn -S HTTP/mywebserver.ad.mydomain.com:20010 MYDOMAIN\mywebserver

setspn -S HTTPS/mywebserver.ad.mydomain.com:20010 MYDOMAIN\mywebserver

setspn -S HTTP/mywebserver.ad.mydomain.com:20010 MYDOMAIN\myserviceaccount

setspn -S HTTPS/mywebserver.ad.mydomain.com:20010 MYDOMAIN\myserviceaccount

每次尝试新的 SPN 时,我都会确保重新启动服务,并完全关闭所有浏览器。

我不知道这些是否正确(我假设它们不正确,因为它回退到 NTLM!)。我不确定是否应该在 mywebserver 或 domainserver 上设置这些。

我尝试将方案设置为 AuthenticationSchemes.Kerberos 仅作为测试,但是当我这样做时,我根本没有得到服务器的响应。

谁能帮我越线?提前致谢!

4

0 回答 0