#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:
Ну, то, что я сделал, чтобы обойти проблемы, подобные описанным выше, заключалось в следующем:
- Настройте учетную запись службы, которая может запрашивать оба 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
тогда все работало нормально.