DirectoryEntry не может изменить пароль из-за контроллера домена. Помогите?

#asp.net #web-services #directoryservices #change-password

#asp.net #веб-сервисы #directoryservices #изменить пароль

Вопрос:

Предполагается, что это базовый метод смены пароля с использованием DirectoryServices в ASP.NET .

Код:

 String path = ConfigurationManager.AppSettings["LDAPServer"]   myDN;
DirectoryEntry de = new DirectoryEntry(path, @"Domain A"   myUserId, myPassword, AuthenticationTypes.Secure);
de.Invoke("ChangePassword", new object[] { myPassword, myNewPassword});
  

Это работает нормально, если я запускаю локально через виртуальный IIS (используя Visual Studio).
Однако, если я опубликую это в рабочей среде, я получу:

Не удалось прочитать информацию о конфигурации с контроллера домена, либо потому, что компьютер недоступен, либо доступ был запрещен. (Исключение из HRESULT: 0x80070547)

Единственное различие между ними может заключаться в том, что мой компьютер находится в домене A, но опубликованный сервер находится в домене B. Домен A и Домен B являются доверенными, а домен A является родительским для домена B.

У кого-нибудь есть идеи, где и как возникает ошибка?

РЕДАКТИРОВАТЬ: Возможно, мне следует добавить, что это веб-сервис. Другое приложение выдаст необходимую информацию для проверки, и веб-служба изменит пароль.

Комментарии:

1. Рабочий IIS работает только с «Аутентификацией Windows»?

2. Да, это единственное отмеченное поле.

3. <Identity impersonate="true" /> внутри web.config?

4. Я пробовал с ним и без него, и сообщение об ошибке одно и то же. ps. Я внес небольшое редактирование в свой пост, указав, что это веб-сервис.

5. Хм .. извините, похоже, что олицетворение выдает ошибку «Отказано в доступе», но из другого раздела кода. Позвольте мне сначала разобраться с этим

Ответ №1:

Ну, то, что я сделал, чтобы обойти проблемы, подобные описанным выше, заключалось в следующем:

  1. Настройте учетную запись службы, которая может запрашивать оба AD

Первый метод

 private bool ResetDomainAccountPassword(string loginName, string oldPassword, string newPassword)
{
  DirectoryEntry e2 = new DirectoryEntry();

  try
  {
    // ----- Get the credentials for the active directory service account.
    string userName = ServiceUser();
    string password = ServicePassword();

    using (DirectoryEntry e = new DirectoryEntry(Path(), userName, password, AuthenticationTypes.Secure))
    {
      string search = string.Format("(sAMAccountName={0})", loginName);

      DirectorySearcher s = new DirectorySearcher(e, search);

      SearchResult sr = s.FindOne();
      if (sr != null)
      {
        e2 = sr.GetDirectoryEntry();
        e2.Username = userName;
        e2.Password = password;
      }

      if (e2.NativeGuid != null)
      {
        return ResetPassword(e2, oldPassword, newPassword);
      }
      else
        return false;
    }
  }
  catch (Exception ex)
  {
    Exception inner = ex.InnerException;

    // ----- Handle exception here.

    return false;
  }
  finally
  {
    e2.Dispose();
  }
}
  

Метод сброса пароля

 private bool ResetPassword(DirectoryEntry e, string oldPassword, string newPassword)
{
  try
  {
    ActiveDs.IADsUser u = e.NativeObject as ActiveDs.IADsUser;
    Type t = e.NativeObject.GetType();
    if (u.IsAccountLocked)
    {
      u.IsAccountLocked = false;
      u.SetInfo();
    }

    u.SetPassword(newPassword);
    u.SetInfo();

    e.CommitChanges();


    return true;
  }
  catch (Exception ex)
  {
    Exception inner = ex.InnerException;

    // ----- Handle exception here.

    return false;
  }
}
  

Одна вещь, которую я забыл: вам нужно добавить ссылку на «Активную библиотеку типов DS» (COM).

Комментарии:

1. Хорошо, после включения олицетворения при попытке запустить процесс будет выдаваться ошибка «Отказано в доступе». Есть идеи, как противостоять этому?

Ответ №2:

Извините, что пометил ваш ответ как ответ и убрал его. На самом деле я получал еще одну ошибку из-за проблемы с идентификацией, и я подумал, что эта проблема решена, и перешел к следующей проблеме.

В любом случае, я решил это, изменив ПУТЬ DirectoryEntry. Раньше это было:

LDAP://server.domain/Distinctedname

но я изменил его на

LDAP://DistinguishedName

тогда все работало нормально.