System.DirectoryServices.DirectoryServicesCOMException(0x8000500C)检查组成员身份时

时间:2017-10-23 15:49:35

标签: c# asp.net active-directory

我有一个ASP.NET应用程序,它调用WCF服务来满足其所有数据访问和业务逻辑需求。

App -> WCF -> DB etc.

应用程序托管在IIS中,自定义用户为ApplicationPoolIdentity。已为Web应用程序启用ASP模拟。 ApplicationPoolIdentity用户具有查询/访问AD组的权限(在其他应用程序中也是如此)。 WCF服务中的所有方法都使用模拟属性进行修饰。

我的问题是,在我的本地开发机器上,当我运行整个层次结构时,该站点能够成功访问AD并相应地查询它。在我发布到开发框(具有相同的设置)后,我在检查成员资格时遇到以下异常。

System.DirectoryServices.DirectoryServicesCOMException (0x8000500C): Unknown error (0x8000500c)
   at System.DirectoryServices.PropertyValueCollection.PopulateList()
   at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
   at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
   at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
   at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
   at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
   at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue)
   at System.DirectoryServices.AccountManagement.GroupPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)

我用来检查的代码如下。

private static bool IsUserMemberOfGroup(string userName, string ntGroupName)
{
   if (userName == null || ntGroupName == null)
   {
      return false;
   }

   userName = userName.Replace($"{Environment.UserDomainName}\\", string.Empty);

   try
   {
      bool result;
      using (var ctx = new PrincipalContext(Environment.UserDomainName == Environment.MachineName
                                               ? ContextType.Machine
                                               : ContextType.Domain, Environment.UserDomainName))
      {
         using (var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, ntGroupName))
         {
            result = grp != null && grp.GetMembers(true)
                                       .Any(m => m.SamAccountName.Equals(
                                               userName, StringComparison.OrdinalIgnoreCase));
         }
      }

      return result;
   }
   catch (Exception ex)
   {
      Log4NetLogManager.LogException($"Error while checking {userName} membership in group {ntGroupName}", ex);

      return false;
   }
}

它在using (var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, ntGroupName))行上失败。

我做错了什么?是否有100%万无一失的方法来避免这种异常?我们在另一个应用程序中积极使用类似的模式,它工作得很漂亮。我已经回顾了两个应用程序及其配置(两者都是ASP.NET)之间的相同点和不同点,但无法找到任何差异。

我还设置了一个测试应用程序,使用两个应用程序使用的代码(工作和破坏的代码)在远程机器上运行,并且无法复制故障。

清单在这里会非常有帮助。

1 个答案:

答案 0 :(得分:0)

最后,我们做了愚蠢的解决方案,并将此逻辑分解为一个小型服务,并指示两个应用程序调用此服务进行组成员身份验证。它可以很好地为两个应用程序工作而没有任何问题。