我有一个MVC Intranet应用程序,我最近从.Net 4升级到4.6.1。此应用程序从Active Directory查询用户详细信息,以加载Controller的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()
网络应用程序在专用的应用程序池上运行,其设置如下:
所有其他设置均为默认设置。应用程序本身在启用匿名和Windows身份验证的情况下运行。服务器安装了.Net 4.6.1,并且Intranet应用程序的所有其他元素似乎运行正常。
将谷歌搜索到死亡后,大多数答案似乎都表明服务帐户查询AD的权限存在问题。为了确认应用程序池正在运行的服务帐户可以访问查询Active Directory,我在控制台应用程序中使用了上述代码并将其作为我自己和服务器上的服务帐户运行 - 两者都在实例它运作得很好。它只能在IIS下运行时爆炸。
我尝试了很多变体来创建PrincipalContext(包括OU容器路径等),但结果总是一样的。
我正在坚持这一点,所以任何帮助都会非常感激。
更新 - 其他详细信息
在System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) 在System.DirectoryServices.DirectoryEntry.Bind()at System.DirectoryServices.DirectoryEntry.get_AdsObject()at System.DirectoryServices.PropertyValueCollection.PopulateList()at System.DirectoryServices.PropertyValueCollection..ctor(的DirectoryEntry entry,String propertyName)at System.DirectoryServices.PropertyCollection.get_Item(字符串 propertyName)at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer() 在 System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit() 在 System.DirectoryServices.AccountManagement.PrincipalContext.Initialize() 在 System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx() 在 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.UserPrincipal.FindByIdentity(PrincipalContext context,IdentityType identityType,String identityValue)at Apollo.Security.ActiveDirectoryUser.Find(String identityName)
答案 0 :(得分:1)
谈论一个令人头疼的问题。我花了一天的时间在这个圈子里走了一圈。
感谢Rahul提供的所有帮助。最后,根据他的建议,我创建了一个新的应用程序池,作为网络服务运行,AD查找在此下完美运行。不幸的是,因为我的应用程序访问网络资源,它需要作为AD用户运行,所以只是为了它,我将凭据更改为我以前一直使用的AD服务帐户并 IT仍然工作 强>
?!
我不知道为什么会出现这种情况 - 两个应用程序池都具有完全相同的设置,但是可以执行查找,而另一个则不能。我已经将测试和生产实例都切换到新的应用程序池并删除了旧的应用程序池,所有内容都很顺利。
答案 1 :(得分:0)
对我们而言,这是由于McAfee HIPS服务通过TCP端口135阻止出站/入站WMI连接