asp.net ядро 3 HTTP.SYS с SSL, Active Directory Kerberos — проблемы с SPN?

#kerberos #windows-authentication #asp.net-core-3.1 #ntlm #spn

#kerberos #windows-аутентификация #asp.net-core-3.1 #ntlm #spn

Вопрос:

Я пытаюсь запустить net core 3 API в качестве службы Windows (т. Е. Не Используя IIS) с помощью Http.Проверка подлинности учетных записей в Active Directory. Я хотел бы, чтобы была включена базовая аутентификация (должна поддерживать non.СЕТЕВЫЕ языки, на которых разработчики запрашивали базовую аутентификацию), но разрешают windows / kerberos, где это возможно.

Я нахожусь на большей части пути, на самом деле у меня в основном есть служба, которая делает все, что я хочу, за исключением 1 вещи — я вижу только, что NTLM используется вместо kerberos. Я мог бы потенциально перейти на prod как есть, но я хотел бы понять, почему я не могу заставить 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)}",
        };
    }
}
 

Я заплатил за соответствующий сертификат, который я настроил на порту 20010 с помощью netsh в скрипте ps1:

  $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 core 3.1
  • запуск под учетной записью домена ‘myserviceaccount’

Учетная запись службы ‘myserviceaccount’ в настоящее время имеет права администратора на веб-сервере, я думаю, что смогу удалить это, если предоставлю разрешения на сертификат непосредственно этой учетной записи. Или, возможно, чтобы все это работало, я должен запустить его как системную учетную запись? Предпочитаю этого не делать.

Active directory:

  • ad.mydomain.com
  • имя сервера netbios: domainserver
  • полное имя сервера: domainserver.ad.mydomain.com

Как есть, это отлично работает со всеми браузерами / ОС и со всех языков, которые настроены на использование службы. Он правильно проверяет, разрешает пользователям домена и показывает соответствующий сертификат. Но, как указано выше, когда я использую различные тестеры аутентификации / скрипача и т. Д., Он показывает только NTLM при доступе с клиентов Windows.

Я попытался установить следующие 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 только в качестве теста, но когда я делаю это, я вообще не получаю ответа от сервера.

Кто-нибудь может помочь мне перейти черту? Заранее спасибо!

Комментарии:

1. Удалите порт из SPN.

2. О, и подтвердите, что имя, к которому вы подключаетесь, на самом деле является записью A в DNS, а не CNAME. Если это CNAME, вам также необходимо зарегистрировать имя записи A в качестве SPN.

3. спасибо за комментарий, Стив — я не уверен на 100%, что понимаю A / CNAME, о котором вы упоминаете. Вы спрашиваете, является ли доменное имя контроллера домена «правильным» зарегистрированным доменом? Если это так, то это не так, это просто «выдуманное» имя, я им публично не владею. Должен ли я устанавливать эти SPN на веб-сервере или сервере AD?

4. …Из SPN. HTTP / mywebserver… представляет DNS-имя. Это DNS-имя указывает на что-то. Является ли «mywebserver» CNAME или записью A? Если это CNAME, это означает, что оно указывает на другую запись, и эта запись должна быть записью с другим именем «mywebserverlongcomplicatedwhatever». Что запись также должна быть зарегистрирована как SPN.