Можно изменить пароль пользователя 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)
Ваша помощь приветствуется. Спасибо.