Setting ASP.Net Permissions - Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

走远了吗. 提交于 2020-01-24 18:20:38

问题


I have an MVC 4 application that allows a user to change their Active Directory password through a password reset functionality page. I have the following piece of code that sets the new password:

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

Upon trying to submit the form with the new password details I am having the following error written to the application event log:

 0x80070005 (E_ACCESSDENIED))

I have set the Identity property of the Application Pool to NetworkService and had thought that this would have resolved the issue of connecting. Is there anything else further I need to ensure so that my ASPNET application can connect to the AD.


回答1:


tl;dr

In our case, this started happening randomly. Turns out it's because our self-signed SSL certificate had expired. After creating a new one in IIS, the problem was resolved.

Explanation

This thread lead me to the cause.

I will briefly recap what SetPassword does here so you can see why you need it. That particular ADSI method really bundles 3 methods under the covers. It first tries to set the password over a secure SSL channel using LDAP. Next, it tries to set using Kerberos set password protocol. Finally, it uses NetUserSetInfo to attempt to set it.

The main problem is that only the first two methods will generally respect the credentials that you put on the DirectoryEntry. If you provide the proper credentials and an SSL channel for instance, the LDAP change password mechanism will work with those credentials...

If you check the NetUserSetInfo method, you will notice there is no place to put a username/password for authorization. In other words, it can only use the unmanaged thread's security context. This means that in order for it to work, it would have to impersonate the username/password combination you provided programmatically first...

LDAP over SSL is apparently the best way to go (and was the method that we had been using), and it appears (clarifications welcome) that once our self-signed SSL certificate had expired, it skipped Kerberos and fell back to NetUserSetInfo, which failed because it was not using the credentials we provided. (Or it just failed on Kerberos, as the poster said he had never seen the credentials passed in for Kerberos)

So after creating a new self-signed certificate (for COMPUTER.DOMAIN.local), the problem was resolved.

Here is the code (in case anyone's looking for it):

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();


来源:https://stackoverflow.com/questions/16569985/setting-asp-net-permissions-access-is-denied-exception-from-hresult-0x80070

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!