Измените пароль Active Directory, используя протокол Kerberos Change-Password и .NET Core 3 - PullRequest
0 голосов
/ 02 ноября 2019

Можно изменить пароль пользователя AD, используя протокол LDAP. Однако если пользователь должен изменить свой пароль при следующем входе в систему (или срок действия пароля истек), то пароль нельзя изменить, если только он не использует учетные данные администратора. Мне удалось решить эту проблему в прошлом с помощью WIN32 API. К сожалению, я не могу использовать WINAPI в среде Linux.

Согласно этой статье :

Когда пользователь изменяет свой пароль, нажимая CTRL + ALT+ УДАЛИТЬ, а затем нажав Изменить пароль, Windows NT до Windows 2003, используется механизм NetUserChangePassword (метод 1), если целью является домен. Начиная с Windows Vista, протокол смены пароля Kerberos используется для учетных записей домена . Если целью является область Kerberos, используется протокол смены пароля Kerberos (метод 3).

Я искал клиент Kerberos, который может работать в .NET Core, и обнаружил SteveSyfuhs/Kerberos.NET.

Читая Протокол смены пароля Kerberos и Образцы Kerberos.NET , я написал следующий код:

using Kerberos.NET;
using Kerberos.NET.Client;
using Kerberos.NET.Credentials;
using Kerberos.NET.Crypto;
using Kerberos.NET.Entities;
using System;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace KerberosDemo
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string activeDirectoryServer = "10.12.34.56:88"; // kdc port
            string domain = "TEST.LOCAL";
            string username = "testuser@" + domain;
            string oldPassword = "123";
            string newPassword = "456";

            using var client = new KerberosClient(activeDirectoryServer);
            var kerbCred = new KerberosPasswordCredential(username, oldPassword, domain);
            await client.Authenticate(kerbCred);
            var serviceTicket = await client.GetServiceTicket("kadmin/changepw");

            var apReq = new KrbApReq
            {
                Ticket = serviceTicket.Ticket,
                Authenticator = KrbEncryptedData.Encrypt(Encoding.UTF8.GetBytes(newPassword).AsMemory(), kerbCred.CreateKey(), KeyUsage.ApReqAuthenticator),
                ProtocolVersionNumber = 1
            };

            var tcp = client.Transports.FirstOrDefault(t => t.Protocol == ProtocolType.Tcp);
            await tcp.SendMessage<KrbApReq, KrbAsRep>(domain, apReq);
        }
    }
}

Я получил следующее исключение в await tcp.SendMessage<KrbApReq, KrbAsRep>(domain, apReq);:

Необработанное исключение. System.Security.Cryptography.CryptographicException: поврежденные данные ASN1. в System.Security.Cryptography.Asn1.AsnReader.ReadTagAndLength (кодируется Nullable 1& contentsLength, Int32& bytesRead) in d:\a\1\s\Kerberos.NET\Asn1\Experimental\AsnReader.cs:line 305 at Kerberos.NET.Entities.KrbError.CanDecode(ReadOnlyMemory 1) в d: \ a \ 1 \ s \ Kerberos.NET \ Entities \ Krb \ KrbError.cs: строка 23 в Kerberos.NET.Transport.KerberosTransportBase.Decode [T] (кодирование ReadOnlyMemory 1 response) in d:\a\1\s\Kerberos.NET\Client\Transport\KerberosTransportBase.cs:line 41 at Kerberos.NET.Transport.TcpKerberosTransport.ReadResponse[T](NetworkStream stream, CancellationToken cancellation) in d:\a\1\s\Kerberos.NET\Client\Transport\TcpKerberosTransport.cs:line 69 at Kerberos.NET.Transport.TcpKerberosTransport.SendMessage[T](String domain, ReadOnlyMemory 1, отмена CancellationToken) в d: \ a \ 1 \ s \ Kerberos.NET \ Client \ Transport \ TcpKerberosTransport.cs: строка 58 в KerberosDemo.Program.Main (строка[] args) в KerberosDemo.Program. (String [] args)

Ваша помощь приветствуется. Спасибо.

1 Ответ

1 голос
/ 04 ноября 2019

Я также могу записать это в ответ.

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

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

Чтобы обойти это, вы можетеиспользовать другую учетную запись для аутентификации в AD. Это не обязательно должна быть учетная запись администратора . Подойдут любые учетные данные домена. Затем вы можете найти учетную запись пользователя.

Поскольку для смены пароля вам нужно знать старый пароль, AD считает , что все необходимые вам полномочия для его изменения.

Это отличается от сброса пароля, когда вам нужна учетная запись с разрешением «Сбросить пароль» для этой учетной записи.

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

Все это описано в документации для атрибута unicodePwd .

...