@rv82
ASP.NET Core разработчик

Как добавить авторизацию через Active Directory в приложение, в котором уже есть авторизация на основе JWT?

Приложение:
  • Backend на .NET Core 3.1 WebAPI
  • Frontend на Vue.
  • Backend работает в Debian. Машина не введена в домен, но если это необходимо, то можно ввести.

Не могу найти ничего конкретного на эту тему, кроме этого документа, в котором практически ничего не рассказывается. А у самого знания в этой области нулевые.
Для тестовых нужд сделал следующее:
  • Создал домен на основе Samba. Контроллер и клиент работают под управлением Debian 10.
    • Имя контроллера: dc1.mydomain.net
    • Domain: MYDOMAIN
    • Realm: MYDOMAIN.NET
    • Машина, на которой запускаю приложение, называется m1.mydomain.net.


  • Добавил в переменную среды KRB5_KTNAME с указанием пути к keytab-файлу:
    • export KRB5_KTNAME=$HOME/krb5.keytab. Предварительно скопировал krb5.keytab из /etc в ~ и выставил на него права на чтение.


  • В файл Startup.cs добавил:
    services
            .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    // ...
                };
            })
            .AddNegotiate(options =>
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    options.EnableLdap(settings =>
                    {
                        settings.Domain = "mydomain.net";
                        settings.MachineAccountName = "administrator";
                        settings.MachineAccountPassword = "...";
                    });
                }
            });
        
        // …
        app.UseAuthentication();
        app.UseAuthorization();



Вопросы:
  1. Что делать дальше? Как проверяется пользователь? Каких-либо примеров найти не удалось.
  2. Что такое MachineAccountName и MachineAccountPassword? Логин и пароль доменного пользователя? И нужны ли они? B нужны ли они? Если я добавляю эти параметры, то получаю исключение: "System.DirectoryServices.Protocols.DirectoryOperationException: Strong authentication is required for this operation".
  3. Нужно ли добавлять какие-то дополнительные SPN в keytab-файл кроме тех, что там уже есть? Сечас keytab содержит следующие записи:

    1 2 host/debian.mydomain.net@MYDOMAIN.NET
    2 2 host/DEBIAN@MYDOMAIN.NET
    3 2 host/debian.mydomain.net@MYDOMAIN.NET
    4 2 host/DEBIAN@MYDOMAIN.NET
    5 2 host/debian.mydomain.net@MYDOMAIN.NET
    6 2 host/DEBIAN@MYDOMAIN.NET
    7 2 host/debian.mydomain.net@MYDOMAIN.NET
    8 2 host/DEBIAN@MYDOMAIN.NET
    9 2 host/debian.mydomain.net@MYDOMAIN.NET
    10 2 host/DEBIAN@MYDOMAIN.NET
    11 2 DEBIAN$@MYDOMAIN.NET
    12 2 DEBIAN$@MYDOMAIN.NET
    13 2 DEBIAN$@MYDOMAIN.NET
    14 2 DEBIAN$@MYDOMAIN.NET
    15 2 DEBIAN$@MYDOMAIN.NET
    16 2 host/m1.mydomain.net@MYDOMAIN.NET
    17 2 host/M1@MYDOMAIN.NET
    18 2 host/m1.mydomain.net@MYDOMAIN.NET
    19 2 host/M1@MYDOMAIN.NET
    20 2 host/m1.mydomain.net@MYDOMAIN.NET
    21 2 host/M1@MYDOMAIN.NET
    22 2 host/m1.mydomain.net@MYDOMAIN.NET
    23 2 host/M1@MYDOMAIN.NET
    24 2 host/m1.mydomain.net@MYDOMAIN.NET
    25 2 host/M1@MYDOMAIN.NET
    26 2 M1$@MYDOMAIN.NET
    27 2 M1$@MYDOMAIN.NET
    28 2 M1$@MYDOMAIN.NET
    29 2 M1$@MYDOMAIN.NET
    30 2 M1$@MYDOMAIN.NET




Буду очень признателен, если кто-нибудь укажет пример. Заранее спасибо!

PS. Посмотрел примеры для .NET Core 2.XX, в частности этот. Подключение к Ldap падает с исключением "Unable to read data from the transport connection: Connection reset by peer". Если в подключении указать "SecureSocketLayer = false", то будет выпадать исключение "Strong Authentication Required", даже если в smb.conf были отключены tls и ssl.

PPS. Хотелось бы пример именно с использованием Microsoft.AspNetCore.Authentication.Negotiate, т.к. это, насколько я понимаю, предпочтительный вариант для ASP.NET Core версии 3.1 и выше.
  • Вопрос задан
  • 917 просмотров
Решения вопроса 1
@rv82 Автор вопроса
ASP.NET Core разработчик
Решение, как оказалось, очень простое и было найдено по горячим следам. Сложнее было настроить сеть с тестовым доменом AD. Только сейчас дошли руки написать ответ. Итак:

1. Добавить к проекту nuget-пакет Microsoft.AspNetCore.Authentication.Negotiate.

2. В файл Startup.cs, в методе ConfigureServices, вслед за services.AddAuthentication(...).AddJwtBearer(...) добавить .AddNegotiate(). Аутентификация JwtBearer остаётся по умолчанию. Больше никаких настроек выполнять не требуется!

3. В контроллере, отвечающем за аутентификацию (в нашем случае AccountController) добавляется метод, например LoginByActiveDirectory, с атрибутом [Authorize(AuthenticationSchemes = NegotiateDefaults.AuthenticationScheme)]. Атрибут указывает, что для доступа к этому методу нужна аутентификация через AD.

4. Перед запуском приложения необходимо задать переменную окружения KRB5_KTNAME с указанием пути к keytab-файлу. Этот файл создаётся на контроллере домена.

PS. Если нужны подробности, то могу набросать более развёрнутую статейку с описанием процесса настройки тестового домена и создания keytab-файла на примере Debian и Samba.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы