我们在ASP.NET MVC 4应用程序中执行了一些代码。该应用程序托管在Windows Server 2012上的IIS中。应用程序池的标识不是标准的,而是特定的用户,例如iis-appPool-username
如下所述。该应用程序在.NET 4.0中运行,并为Managed Pipeline设置了集成模式。
DirectoryEntry
对象中指定了用户名,我都尝试了它。 AuthenticationTypes.ReadonlyServer
之前,控制台应用不工作,因为它是只读的域控制器。在我指定LDAP路径和Readonly类型之前,它为控制台应用程序提供了相同的错误。但是,虽然控制台应用程序现在可以使用,但IIS应用程序却没有。代码如下。
// also tried: var searchRoot = new DirectoryEntry(@"LDAP://DC=subdom,DC=ourdomain,DC=com");
var searchRoot = new DirectoryEntry(@"LDAP://DC=subdom,DC=ourdomain,DC=com", @"domain\iis-appPool-username", "password");
searchRoot.AuthenticationType = AuthenticationTypes.ReadonlyServer;
using (var searcher = new DirectorySearcher(searchRoot))
{
searcher.Filter = string.Format("(&(objectClass=group)(sAMAccountName={0}))", "someGroupName");
searcher.PropertiesToLoad.Add("distinguishedName");
// This is where the failure happens
var result = searcher.FindOne();
}
堆栈跟踪的错误如下所示:
System.Runtime.InteropServices.COMException (0x8007054B):
The specified domain either does not exist or could not be contacted.
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at 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(String propertyName)
at System.DirectoryServices.DirectorySearcher.get_SearchRoot()
at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
at System.DirectoryServices.DirectorySearcher.FindOne()
编辑:此外,如果我明确使用错误的用户名和密码,则会出现同样的错误。从我的本地机器,如果我使用错误的用户名和密码,我得到一个auth错误。但是,从IIS,用户名和密码错误,它甚至都没有那么远。
编辑:我在web.config中指定以完全信任的方式运行:
<securityPolicy>
<trustLevel name="Full" policyFile="internal"/>
</securityPolicy>
我们还在框中为用户提供了管理员权限。继续收到同样的错误:System.Runtime.InteropServices.COMException: The specified domain either does not exist or could not be contacted.
更新:所以,这最终是两个问题的组合。
1)正如下面提到的@Hans,我最初错过了DirectoryEntry
DirectorySearcher
参数。在我尝试不同的可能性,组合的过程中,当我有一个工作的控制台应用程序并且正在更新应用程序代码以反映它时,我设法错过了这个更改。
2)当我将参数添加到DirectorySearcher
时,我仍然收到错误。消息相同,堆栈跟踪几乎相同。堆栈跟踪中间有1行不同 - 对另一个需要DirectoryEntry
参数的方法的辅助调用在其自己的DirectorySearcher
中使用。我一直在看问题这个问题,我的眼睛只看到相同的错误信息和看起来是相同的堆栈跟踪,实际上它是一个新的。将DirectoryEntry
对象传递给那些调用可以解决这个问题。
最终的解决方案不要求我在路径中有一个服务器标识符(但如果您的环境无法解析域控制器,您的里程可能会有所不同。)
答案 0 :(得分:5)
您必须按顺序指定DirectorySearcher
类的搜索根
连接到Active Directory域控制器。
如果不这样做,您将获得 COM异常(0x8007054B)
指定DirectorySearcher
类的搜索根。
请尝试以下代码行:
var searchRoot = new DirectoryEntry(@"LDAP://DC=subdom,DC=ourdomain,DC=com", @"domain\iis-appPool-username", "password");
searchRoot.AuthenticationType = AuthenticationTypes.ReadonlyServer;
using (var searcher = new DirectorySearcher(searchRoot)) // Specify the search root here
{
searcher.Filter = string.Format("(&(objectClass=group)(sAMAccountName={0}))", "someGroupName");
searcher.PropertiesToLoad.Add("distinguishedName");
var result = searcher.FindOne();
}