我有一个最近从 .Net 4 升级到 4.6.1 的 MVC Intranet 应用程序。此应用程序从 Active Directory 查询用户详细信息,以加载控制器的 User.Identity 属性中不可用的详细信息,并且直到最近才完美地完成了此操作。代码看起来像这样:
public static void foo()
{
var usr = LookupUser("MyDomain", "jbloggs");
...
}
private static UserPrincipal LookupUser(string domain, string username)
{
Console.WriteLine($"Lookup {domain}\\{username}");
using (var ctx = new PrincipalContext(ContextType.Domain, domain))
{
using (var user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, username))
{
if (user == null)
{
Console.WriteLine("User not found");
return;
}
Console.WriteLine($"Found {domain}\\{username}");
Console.WriteLine($"DisplayName = {user.DisplayName}");
Console.WriteLine($"Office = {user.GetString("physicalDeliveryOfficeName")}");
Console.WriteLine("");
return user;
}
}
}
该代码在 Visual Studio 2015 中调试时运行良好,但在 IIS 框(Windows Server 2008 R2 上的 v6.1 SP1)上运行时,调用 UserPrincipal.FindByIdentity() 时会引发 COMException (0x80005000)
Web 应用程序运行在专用的应用程序池上,其设置如下:
- .Net 框架版本 = v4.0
- Identity = MyDomain\MyAppServiceUser(非交互式 AD 用户帐户)
- 加载用户配置文件 = false
所有其他设置均按照默认设置。应用程序本身在启用匿名和 Windows 身份验证的情况下运行。服务器已安装 .Net 4.6.1,并且 Intranet 应用程序的所有其他元素似乎运行良好。
在谷歌上搜索到死后,大多数答案似乎表明这是服务帐户查询 AD 的权限问题。为了确认应用程序池运行的服务帐户是否有权查询 Active Directory,我在控制台应用程序中使用了上述代码,并将其作为我自己和服务器上的服务帐户运行 - 在两者中实例它工作得很好。它只有在 IIS 下运行时才会崩溃。
我尝试了许多创建 PrincipalContext 的变体(包括 OU 容器路径等),但结果始终相同。
我正在为此努力,所以任何帮助将不胜感激。
更新 - 其他详细信息
- 异常类型:System.Runtime.InteropServices.COMException
- 异常消息:未知错误 (0x80005000)
- 堆栈跟踪:
在 System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) 在 System.DirectoryServices.DirectoryEntry.Bind() 在 System.DirectoryServices.DirectoryEntry.get_AdsObject() 在 System.DirectoryServices.PropertyValueCollection.PopulateList() 在 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 System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx() 中的 System.DirectoryServices.AccountManagement.Principal 中的 .PrincipalContext.Initialize()。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.UserPrincipal .FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue) at Apollo.Security.ActiveDirectoryUser.Find(String identityName)DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue) at Apollo.Security.ActiveDirectoryUser.Find(String identityName)DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue) at Apollo.Security.ActiveDirectoryUser.Find(String identityName)