Установка разрешений ASP.Net - доступ запрещен. (Исключение из HRESULT: 0x80070005 (E_ACCESSDENIED))
У меня есть приложение MVC 4, которое позволяет пользователю изменять свой пароль Active Directory через страницу функциональности сброса пароля. У меня есть следующий кусок кода, который устанавливает новый пароль:
DirectoryEntry de = sr.GetDirectoryEntry();
de.Invoke("SetPassword", new object[] { newPassword });
de.Properties["LockOutTime"].Value = 0;
При попытке отправить форму с новым паролем у меня появляется следующая ошибка в журнале событий приложения:
0x80070005 (E_ACCESSDENIED))
Я установил для свойства Identity пула приложений значение NetworkService и подумал, что это решило бы проблему подключения. Есть ли что-то еще, что мне нужно, чтобы мое приложение ASPNET могло подключаться к AD.
1 ответ
ТЛ; др
В нашем случае это начало происходить случайно. Оказывается, это потому, что срок действия нашего самоподписанного сертификата SSL истек. После создания нового в IIS проблема была решена.
объяснение
Эта тема привела меня к делу.
Я кратко напомню, что
SetPassword
здесь, чтобы вы могли понять, зачем вам это нужно. Этот конкретный метод ADSI действительно объединяет 3 метода под одеялом. Сначала он пытается установить пароль по безопасному каналу SSL, используя LDAP. Затем он пытается установить протокол Kerberos с установленным паролем. Наконец, он используетNetUserSetInfo
попытаться установить его.Основная проблема заключается в том, что только первые два метода обычно учитывают учетные данные, которые вы
DirectoryEntry
, Если вы предоставите правильные учетные данные и канал SSL, например, механизм изменения пароля LDAP будет работать с этими учетными данными...Если вы проверите метод NetUserSetInfo, вы заметите, что нет места для ввода имени пользователя / пароля для авторизации. Другими словами, он может использовать только контекст безопасности неуправляемого потока. Это означает, что для того, чтобы он работал, ему сначала нужно выдать себя за комбинацию имени пользователя и пароля, которую вы указали программно...
LDAP через SSL, по-видимому, является наилучшим способом (и это был метод, который мы использовали), и кажется (пояснения приветствуются), когда истек срок действия нашего самоподписанного сертификата SSL, он пропускает Kerberos и возвращается к NetUserSetInfo
, что не удалось, потому что он не использовал учетные данные, которые мы предоставили. (Или это просто не удалось на Kerberos, так как на плакате говорилось, что он никогда не видел учетные данные, переданные для Kerberos)
Таким образом, после создания нового самозаверяющего сертификата (для COMPUTER.DOMAIN.local
), проблема была решена.
Вот код (на тот случай, если кто-то его ищет):
DirectoryEntry myDE = new DirectoryEntry(@"LDAP://OU=GroupName,DC=DOMAIN,DC=local");
myDE.Username = "administrator";
myDE.Password = "adminPassword";
DirectoryEntries myEntries = myDE.Children;
DirectoryEntry myDEUser = myEntries.Find("CN=UserName");
myDEUser.Invoke("SetPassword", new object[] { "NewPassword" });
myDEUser.Properties["LockOutTime"].Value = 0;
// the following 2 lines are free =)
myDEUser.Properties["userAccountControl"].Value = (int)myDEUser.Properties["userAccountControl"].Value | 0x10000; // don't expire password
myDEUser.Properties["userAccountControl"].Value = (int)myDEUser.Properties["userAccountControl"].Value & ~0x0002; // ensure account is enabled
myDEUser.CommitChanges();