Изменение пароля Active Directory LDAP через C # ASP.NET: невозможно прочитать конфигурацию - PullRequest
0 голосов
/ 18 декабря 2018

Мы пытаемся изменить пароли пользователей в Active Directory (мы будем использовать «Jane» в качестве примера пользователя) через приложение C # ASP.NET 4.5, хотя мы получаем ошибку ниже.

Configuration information could not be read from the domain controller, either because the machine is unavailable, or access has been denied. (Exception from HRESULT: 0x80070547)

Соединение с удаленным (сторонним) сервером AD может быть установлено без проблем, и наш сервисный пользователь аутентифицирован.Запись каталога Джейн также может быть получена без проблем.

Мы попытались изменить / установить пароль во время аутентификации как Джейн, так и нашего пользователя службы, и оба выдают одну и ту же ошибку (см. Выше).

Ниже приведен пример используемого кода.

using (var context = new PrincipalContext(ContextType.Domain, ServiceDomain, ServiceDefaultLocation, ContextOptions.Negotiate, ServiceUser, ServicePassword))
using (var identity = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "Jane"))
{
    // identity.SetPassword("SomeNewPassword"); // also tried
    identity.ChangePassword("TheOldPassword", "SomeNewPassword"); // this is the error line
    identity.Save();
}

Журнал системных событий указывает на сбой аудита при изменении / установке пароля, причина которого указана как «Произошла ошибка при входе в систему».Пакет аутентификации содержит список «MICROSOFT_AUTHENTICATION_PACKAGE_V1_0».До этого у нас есть событие Audit Success против нашего пользователя службы.

Стоит отметить, что это прибл.За 20 секунд до того, как мы получим сообщение об ошибке, указывающее на то, что это может быть проблема соединения / тайм-аута, однако исходящие соединения не ограничены, и наш IP-адрес внесен в белый список на удаленном конце (опять же, мы можем подключиться и получить запись пользователя).Это может также занять много времени для аутентификации пользователя, хотя (что все еще успешно работает).

Наш пользователь службы имеет права, установленные для изменения / установки паролей других пользователей, но не для непосредственного изменения атрибутов пользователя, поэтомунам сообщили.

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

Ответы [ 3 ]

0 голосов
/ 18 декабря 2018

У меня была похожая проблема с веб-страницей сервера сброса пароля, чтобы пользователи могли сбросить свой пароль.Я обнаружил, что домен был настроен не слишком, чтобы разрешить это, даже если учетной записи службы было дано разрешение просто сбросить пароли.Вы пытались предоставить права администратора домена учетной записи службы просто для проверки того, что это не проблема с разрешениями?

0 голосов
/ 19 декабря 2018

Так UserPrincipal.ChangePassword() будет вызывать :

de.Invoke("ChangePassword", new object[] { oldPassword, newPassword });

на DirectoryEntry, который используется за кадром.DirectoryEntry.Invoke() используется для вызова «метода в собственном объекте доменных служб Active Directory», что означает, что в конечном итоге будет использован собственный метод Windows IADsUser::ChangePassword. Замечания для этого говорит, что он использует один из 3 методов:

IADsUser :: ChangePassword функционирует аналогично IADsUser :: SetPassword в том, что он будет использовать одиниз трех способов, чтобы попытаться изменить пароль.Первоначально поставщик LDAP будет пытаться выполнить операцию изменения пароля LDAP, если установлено безопасное SSL-соединение с сервером.Если эта попытка не удалась, поставщик LDAP затем попытается использовать Kerberos (см. IADsUser :: SetPassword для некоторых проблем, которые могут привести к Windows с проверкой подлинности между лесами), и если это также не удается, он, наконец, вызовет определенную сеть Active DirectoryAPI управления, NetUserChangePassword .

Замечания IADsUser::SetPassword говорят немного больше:

  • Первыйпоставщик LDAP пытается использовать LDAP через 128-битное соединение SSL.Для успешной работы SSL LDAP на сервере LDAP должен быть установлен соответствующий сертификат проверки подлинности сервера, а клиенты, работающие с кодом ADSI, должны доверять органу, выдавшему эти сертификаты.И сервер, и клиент должны поддерживать 128-битное шифрование.
  • Во-вторых, если соединение SSL не удается, поставщик LDAP пытается использовать Kerberos.
  • В-третьих, если Kerberos не удается,Поставщик LDAP пытается выполнить API-вызов NetUserSetInfo .В предыдущих выпусках ADSI вызывал NetUserSetInfo в контексте безопасности, в котором выполнялся поток, а не в контексте безопасности, указанном в вызове IADsOpenDSObject :: OpenDSObject или ADsOpenObject .В более поздних выпусках это было изменено, чтобы поставщик ADSI LDAP выдавал себя за пользователя, указанного в вызове OpenDSObject, когда он вызывает NetUserSetInfo.

Так что, если это вообще не работает для вас,это означает, что все три метода дают сбой.

Я действительно не знаю, как работает Kerberos или NetUserSetInfo, но я знаю, как работает LDAP через SSL, и вы обязательно попробуете, посмотрите, будет ли он работать для вас..

Это должно быть так же просто, как поставить :636 в конце вашего ServerDomain для подключения к порту LDAPS (при условии, что это DNS-имя домена):

using (var context = new PrincipalContext(ContextType.Domain, $"{ServiceDomain}:636", ServiceDefaultLocation, ContextOptions.Negotiate, ServiceUser, ServicePassword))
using (var identity = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "Jane"))
{
    // identity.SetPassword("SomeNewPassword"); // also tried
    identity.ChangePassword("TheOldPassword", "SomeNewPassword"); // this is the error line
    identity.Save();
}

Но вы можете столкнуться с проблемами, если сервер использует сертификат, которому компьютер, на котором вы запускаете, не доверяет (вам придется установить корневой сертификат на компьютере, с которого вы его запускаете).И также возможно, что LDAPS просто не работает на DC.

Но стоит попробовать.

0 голосов
/ 18 декабря 2018

Вы пробовали DirectoryEntry?С этим легче отлаживать проблемы, связанные с подключением.

var entry = new DirectoryEntry{
        Path = "LDAP://yourDCname";
        Username = yourUsername;
        Password = yourPassword;
    };

    using(var searcher = new DirectorySearcher(entry))
    {
        searcher.Filter = "(sAMAccountName=Jane)";
        var result = searcher.FindOne();
        var user = result.GetDirectoryEntry();

        try
        {
            user.Invoke("ChangePassword", new object[] { oldPassword, newPassword});
            user.CommitChanges();
        }
        catch
        {
            throw;
        }

    }

Я также однажды забыл плагин ZenMate VPN, работающий в Google Chrome на заднем плане.Поэтому я не смог подключиться к контроллеру домена.

...