.GetDirectoryEntry throws COM exception, code:0x800720720 when attempting to bind to object

亡梦爱人 提交于 2020-01-03 03:46:13

问题


My application is running on IIS 7.0, it is supposed to impersonate the authenticated user and unlock or reset other user accounts. It worked fine when I was developing it on my workstation, but when I uploaded it to the server the impersonation stopped working, it won't bind to the AD objects and keeps throwing the same exception. I had the same problem earlier with using PrincipalContext but I was able to get around that using using(HostingEnvironment.Impersonate()) because I didn't need the authenticated user for that action. But now I do so I can't use that workaround. I need an actual fix for the issue and I would really appreciate some input. I've been searching far and wide for a solution to the problem and so far none of them have worked. Here is the code I'm using that keeps throwing the exception.

using (DirectorySearcher search = new DirectorySearcher(directoryEntries[counter]))
{
    //Sets the filter to find a user object with the target user username
    search.Filter = "(&(objectClass=user)(sAMAccountName=" + username + "))";
    //Sets the searchscope to search the whole AD
    search.SearchScope = SearchScope.Subtree;
    //Executes the search for one result and stores it in result.
    SearchResult result = search.FindOne();
    //Creates a directory entry from the result.

    using (DirectoryEntry targetUser = result.GetDirectoryEntry())
    {
        //This if-else statement checks if the user is locked, if it is then
        //the unlock is performed, and the unlockPerformed variable is set to
        //true, if it isn't then unlockPerformed is set to false.
        if (Convert.ToBoolean(targetUser.InvokeGet("IsAccountLocked")))
        {
            targetUser.InvokeSet("IsAccountLocked", false);
            targetUser.CommitChanges();
            unlockPerformed = true;
        }
        else
        {
            unlockPerformed = false;
        }
    }
}

This code worked perfectly before I uploaded it, any suggestions are greatly appreciated, I'll be monitoring this so I can get a fix asap. Thanks in advance.

UPDATE: FIXED THE ISSUE

Apparently the program running from the hosting machine but not from a remote machine is actually a very telling symptom according to this article: http://msdn.microsoft.com/en-us/library/vstudio/ms730088(v=vs.100).aspx . According to that article, the problem is that the impersonate setting was set to impersonation which causes this behaviour, I wanted DELEGATION. In order to do this I used this page to get information on different methods of delegation and impersonation, I used the "Impersonating Original Caller Temporarily" section.

In the web.config file:

 <identity impersonate="false"/>

If this is set to false then it tries to impersonate the user for every action, which can cause issues like the one I was experiencing and isn't what I was trying to achieve.

In the code:

using System.Security.Principal;
...
// Obtain the authenticated user's Identity
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
  // Start impersonating
  ctx = winId.Impersonate();
  // Now impersonating
  // Access resources using the identity of the authenticated user
}
// Prevent exceptions from propagating
catch
{
}
finally
{
  // Revert impersonation
  if (ctx != null)
    ctx.Undo();
}
// Back to running under the default ASP.NET process identity

This fix is fairly easy, but its damn near impossible to find good clear information on this topic, I hope someone will find this useful some day, I can't be the only one experiencing these issues.


回答1:


Apparently the program running from the hosting machine but not from a remote machine is actually a very telling symptom according to this article: http://msdn.microsoft.com/en-us/library/vstudio/ms730088(v=vs.100).aspx . According to that article, the problem is that the impersonate setting was set to impersonation which causes this behaviour, I wanted DELEGATION. In order to do this I used this page to get information on different methods of delegation and impersonation, I used the "Impersonating Original Caller Temporarily" section.

In the web.config file:

<identity impersonate="false"/>

If this is set to false then it tries to impersonate the user for every action, which can cause issues like the one I was experiencing and isn't what I was trying to achieve.

In the code:

using System.Security.Principal;
...
// Obtain the authenticated user's Identity
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
  // Start impersonating
  ctx = winId.Impersonate();
  // Now impersonating
  // Access resources using the identity of the authenticated user
}
// Prevent exceptions from propagating
catch
{
}
finally
{
  // Revert impersonation
  if (ctx != null)
    ctx.Undo();
}
// Back to running under the default ASP.NET process identity

This fix is fairly easy, but its damn near impossible to find good clear information on this topic, I hope someone will find this useful some day, I can't be the only one experiencing these issues.



来源:https://stackoverflow.com/questions/24271350/getdirectoryentry-throws-com-exception-code0x800720720-when-attempting-to-bin

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