我有一个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)之间的相同点和不同点,但无法找到任何差异。
我还设置了一个测试应用程序,使用两个应用程序使用的代码(工作和破坏的代码)在远程机器上运行,并且无法复制故障。
清单在这里会非常有帮助。
答案 0 :(得分:0)
最后,我们做了愚蠢的解决方案,并将此逻辑分解为一个小型服务,并指示两个应用程序调用此服务进行组成员身份验证。它可以很好地为两个应用程序工作而没有任何问题。