Клиент-серверное приложение, как создать процесс на удаленной системе в качестве пользователя домена, не передавая имя пользователя / пароль этого пользователя в удаленную систему? - PullRequest
0 голосов
/ 11 апреля 2019

У меня две системы, в которых запущен мой программный код клиент / сервер C #. Я хочу, чтобы с Компьютера 1 создавался процесс в качестве данного пользователя домена Active Directory на Компьютере 2 без необходимости, чтобы программное обеспечение моего клиента / сервера отправляло имя пользователя и пароль пользователя AD в виде простого текста с Компьютера 1 на Компьютер 2.

Самое близкое, что я получил, это то, что я мог использовать функцию KerberosRequestorSecurityToken на компьютере 1, чтобы сгенерировать билет Kerberos, а затем отправить этот результат [] через мой клиент-серверный код на компьютер 2, где он затем сможет вызовите KerberosReceiverSecurityToken для переданного билета kerteos byte []. Если все это работает, то KerberosReceiverSecurityToken будет иметь свойство WindowsIdentity, которое я затем смогу использовать для создания процесса на компьютере 2 с учетной записью пользователя, изначально указанной на компьютере 1 через поток KerberosRequestorSecurityToken.

Мне нужно использовать существующие учетные записи пользователей домена, которые я хочу выдать за себя, вместо регистрации служебной учетной записи SPN. Это суть проблемы, о которой я не упомянул, когда впервые опубликовал вопрос.

Кажется, я не могу заставить это работать, но больше, поэтому я даже не знаю, возможно ли это на самом деле - например, должны ли эти API даже позволять мне делать то, что я хочу?

Код компьютера 1 для генерации билета Kerberos. Результат этого байта [] отправляется через мое клиент-серверное приложение на компьютер 2.

public static byte[] GetRequestToken(string userName, string password, string domain)
{
    using (var domainContext = new PrincipalContext(ContextType.Domain, domain))
    {
        using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName))
        {
            Console.WriteLine("User Principal name" + UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName).UserPrincipalName);
            string spn = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName).UserPrincipalName;
            KerberosSecurityTokenProvider k1 = new KerberosSecurityTokenProvider(spn, TokenImpersonationLevel.Impersonation, new NetworkCredential(userName, password, domain));
            KerberosRequestorSecurityToken T1 = k1.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
            var req = T1.GetRequest();
            return req;
        }
    }
}

Компьютер 2 берет полученный результирующий байт [] билет Kerberos и пытается получить его для доступа к WindowsIdentity, но выдает исключение, сообщающее о недопустимом входе в систему.

KerberosReceiverSecurityToken receiverToken = new KerberosReceiverSecurityToken(requestToken);
byte[] receiverTokenTicket = receiverToken.GetRequest();

//Identity for impersonation
var impersonatedIdentity = receiverToken.WindowsIdentity;

1 Ответ

1 голос
/ 12 апреля 2019

Источник первого блока кода функционально неверен. SPN должен быть целью получения билета, а не пользователем, запрашивающим билет. Так что вам нужно сделать следующие вещи ...

  1. Зарегистрируйте основную учетную запись службы (пользователь / компьютер) в AD.
  2. Добавьте имя участника службы в эту учетную запись в форме foo/host.domain.com, где foo - имя вашей службы, например, http или host, или myapp.
  3. Клиент должен запросить билет на foo/host.domain.com
  4. KerberosReceiverSecurityToken должен разобрать , что билет

Теперь у вас есть личность разного уровня подражания. Этот уровень олицетворения определяет, можете ли вы запустить процесс от имени этого пользователя. Как это происходит ... вы просто не можете, потому что это не так, как работает безопасность Windows. У вас есть NT-маркер олицетворения, так как вы олицетворяете пользователя, в то время как вам нужен первичный NT-токен для запуска процессов.

Таким образом, вам нужно преобразовать это в основной токен, используя DuplicateTokenEx , и для этого вам необходимо быть SYSTEM.

Получив основной токен, вы можете вызвать CreateProcessAsUser .

В этот момент вы могли запустить процесс как пользователь, но у него нет учетных данных для доступа к другим сетевым свойствам, таким как сетевые ресурсы или веб-службы. Для этого вы можете включить ограниченное делегирование субъекта службы любым нисходящим службам.

Альтернативный и, возможно, более безопасный и простой вариант - вместо этого запустить рабочий процесс как пользователь с низкими привилегиями и сообщить , что процесс олицетворяется. См. этот ответ для получения дополнительной информации об этом.

...