2013-05-15 6 views
2

У меня есть приложение MVC 4, которое позволяет пользователю изменять свой пароль Active Directory с помощью страницы функциональности сброса пароля. У меня есть следующий фрагмент кода, который устанавливает новый пароль:Настройка разрешений ASP.Net - доступ запрещен. (Исключение из HRESULT: 0x80070005 (E_ACCESSDENIED))

DirectoryEntry de = sr.GetDirectoryEntry(); 
de.Invoke("SetPassword", new object[] { newPassword }); 
de.Properties["LockOutTime"].Value = 0; 

При попытке отправить форму с новыми деталями пароля Я имею следующее сообщение об ошибке записывается в журнал событий приложений:

0x80070005 (E_ACCESSDENIED)) 

Я установил свойство Identity пула приложений в NetworkService и подумал, что это решит проблему подключения. Есть ли еще что-то еще, что мне нужно для обеспечения того, чтобы приложение ASPNET могло подключаться к AD.

+0

ли учетная запись NetworkService имеют доступ к структуре AD, и, в частности, это индивидуальное разрешение? –

+0

Я использовал ASP Impersonate true и использовал учетную запись с полными правами на структуру AD, но я все еще получаю эту ошибку ACCESS_DENIED – Jay

+0

Это проблема, которая недавно появилась на нашем сервере без видимого катализатора (без обновлений Windows, изменений IIS или изменения кода, которые повлияли на эту функциональность) – snumpy

ответ

1

Т.Л., др

В нашем случае, это началось случайно происходит. Оказывается, это связано с тем, что наш самоподписанный сертификат SSL истек. После создания нового в IIS проблема была решена.

Объяснение

This thread приводят меня к делу.

Вкратце повторю, что делает SetPassword, чтобы вы могли понять, зачем вам это нужно. Этот специальный метод ADSI действительно связывает 3 метода под обложками. Сначала он пытается установить пароль по защищенному каналу SSL с помощью LDAP. Затем он пытается установить протокол Kerberos set password. Наконец, он использует 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(); 
Смежные вопросы