#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.